Somehash:一次受 Blurhash 启发的探索
Somehash: A Blurhash-Inspired Exploration

原始链接: https://travisbumgarner.dev/blog/somehash

“Somehash” 项目是一个受 Blurhash 启发的占位符图片探索项目,旨在提升网站加载过程中的用户体验。整个过程包含三个关键步骤:处理、占位和加载。 该项目使用 Python 中的 KMeans 聚类算法提取图像的主色调,将其编码成字符串,并与图像的纵横比一起存储这个“哈希值”。这些数据随后传递给一个 React 组件。 React 组件解码哈希值并渲染动画——在本例中,使用提取的颜色渲染垂直线条。这在加载全分辨率图像时充当视觉占位符。该项目使用了 Pillow、NumPy 和 scikit-learn 等 Python 库进行图像处理,并使用 React 进行渲染。 未来的改进包括简化编码/解码过程,将动画与图像的 `onload` 事件连接起来以实现更平滑的过渡,以及关注生产就绪性。作者鼓励读者思考在网站加载时间内自己创造性的占位符图像解决方案。

Hacker News 最新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 Somehash:一次受 Blurhash 启发的探索 (travisbumgarner.dev) 3 分,来自 theogravity,1 小时前 | 隐藏 | 过去 | 收藏 | 讨论 加入我们,参加 6 月 16-17 日在旧金山举办的 AI 初创企业学校! 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系我们 搜索:

原文

Somehash: A Blurhash Inspired Exploration

(Jump Ahead: Demo and Code)

Humans have short attention spans. Websites take time to load. What can be done to prevent visitors from leaving?

Blurhash, shown below, is one such solution. It offers quick loading placeholder images that do a great job of capturing the attention of visitors until the actual content is ready.

Blurhash in Action
Blurhash in Action

This in-between space is rather interesting, often neglected, and rarely explored. Let's go on a journey and build an image placeholder, Somehash, from scratch.

Overview

The journey of an image occurs in three stages: processing, placeholding, and loading. First, information is extracted from the image, hashed, and stored. Next, a React component retrieves the hash and renders a placeholder image. Finally, the full-resolution image is loaded.

Creative Exploration

The first step to creating Somehash is deciding what it will display. The creative possibilities are endless. There are tons of algorithms for extracting interesting colors, textures, patterns, gradients, and more from images.

There are two questions that need answering in this creative exploration.

What information should be extracted?

The information that is extracted should be small. Blurhash extracts about 20 bytes of data per image.

KMeans clustering is a fascinating algorithm. One application is to find dominant colors from an image. The screenshot below shows an example.

Dominant colors extracted from a photo
Dominant colors extracted from a photo

How will the extracted information be displayed?

Whatever effect that is chosen should occur quickly and work on both fast and slow internet connections.

Data Extraction

(Data Extraction Code, Extracted Data)

The first step is processing the images for the website. This is a computationally intensive task, often taking several seconds per image to extract the necessary information. To handle this efficiently, the processing is done using a script that runs outside the browser.

Selecting Tools

The language of choice for this task will be Python. Python has an amazing collection of libraries such as Pillow, NumPy, scikit-learn, and OpenCV for reading and analyzing images.

Extracting Image Data

With the help of sklearn, the process of color extraction is straightforward.

kmeans = KMeans(n_clusters=num_colors)
kmeans.fit(pixels)
colors = kmeans.cluster_centers_.astype(int)

Note: Extracting Aspect Ratios

A thumbnail doesn't have the same dimensions as the image it represents, and similarly, a Somehash shouldn't store width and height. However, to prevent cumulative layout shift, it's essential to know the aspect ratio of the space the Somehash will temporarily occupy. Therefore, alongside the Somehash, the aspect ratio is also stored.

Encoding Data

The next step is to transfer information from the Python script to React. The data will be formatted in a way that ensures it can be easily transferred between the two.

color_string = '_'.join([f'{r}-{g}-{b}' for r, g, b in colors])
encoded_bytes = base64.b64encode(color_string.encode('utf-8'))
encoded_string = encoded_bytes.decode('utf-8')

Additionally, a version field will be added so that different renderers can be used.

return {
    'version': 'animated_lines', 
    'hash': encoded_string, 
    'aspect_ratio': aspect_ratio
}

Placeholder Rendering

(Demo, React Component Code)

Decode Data in React

This step is the opposite of the previous step. The data stored in the JSON file is decoded and passed to the component responsible for rendering the specific version of the hash. In this case, it'll be five interesting colors extracted with KMeans.

React Renderer

The extracted colors are converted into vertical lines that animate on the screen.

At this point, the image starts loading, loads, and then takes the place of the placeholder.

Areas of Improvement

Encoding / Decoding

The data is small enough that it could probably be moved around inside of the JSON object without needing the additional step of Base64 encoding.

Placeholder to Full Image Transition

Currently, when the animation completes, it will display whatever is loaded. It would be best if the animation was instead connected to the image's onload event for a more seamless transition.

Production Readiness

This project explored the minimum path to complete the process. Production readiness was not considered.

Over to You

If you had creative control over the time between the page loading and being loaded - what would you create? Let me know!

联系我们 contact @ memedata.com