travis_bumgarner_proto_final.cpp

我是一个终身学习者、创造者、探索者和修补匠。这是我的经验集合。

Somehash: 一种受 Blurhash 启发的探索

发布于 2025 年 2 月 8 日星期六

(跳转至: 演示代码)

人们的注意力持续时间很短。网站加载需要时间。可以做些什么来防止访客离开?

Blurhash,如下所示,就是这样一种解决方案。它提供快速加载的占位符图像,在实际内容准备好之前,能很好地吸引访客的注意力。

Blurhash in ActionBlurhash 实战

这个中间空间非常有趣,经常被忽视,很少被探索。让我们开始一段旅程,从头开始构建一个图像占位符,Somehash。

概述

图像的旅程分为三个阶段:处理、占位和加载。首先,从图像中提取信息,进行哈希处理并存储。接下来,一个 React 组件检索哈希并渲染占位符图像。最后,加载全分辨率图像。

创意探索

创建 Somehash 的第一步是决定它将显示什么。创意可能性是无限的。有大量的算法可以从图像中提取有趣的颜色、纹理、图案、渐变等等。

在这个创意探索中,需要回答两个问题。

应该提取什么信息?

提取的信息应该很小。Blurhash 每个图像提取大约 20 字节的数据。

KMeans clustering 是一种很棒的算法。一个应用是从图像中找到主色。下面的截图显示了一个例子。

Dominant colors extracted from a photo从照片中提取的主色

将如何显示提取的信息?

无论选择什么效果,都应该快速发生,并且在快速和慢速互联网连接上都能工作。

数据提取

(数据提取代码, 提取的数据)

第一步是处理网站的图像。这是一项计算密集型任务,通常每个图像需要几秒钟才能提取必要的信息。为了有效地处理这个问题,处理过程是使用在浏览器之外运行的脚本完成的。

选择工具

此任务的选择语言将是 Python。Python 拥有一系列令人惊叹的库,例如 Pillow, NumPy, scikit-learn, 和 OpenCV 用于读取和分析图像。

提取图像数据

借助 sklearn,颜色提取过程非常简单。

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

注意:提取宽高比

缩略图与它所代表的图像的尺寸不同,同样,Somehash 也不应该存储宽度和高度。但是,为了防止 cumulative layout shift,必须知道 Somehash 将临时占据的空间的宽高比。因此,除了 Somehash 之外,还存储了宽高比。

编码数据

下一步是将信息从 Python 脚本传输到 React。数据将以一种确保可以在两者之间轻松传输的方式进行格式化。

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')

此外,将添加一个版本字段,以便可以使用不同的渲染器。

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

占位符渲染

(演示, React 组件代码)

在 React 中解码数据

此步骤与上一步相反。存储在 JSON 文件中的数据被解码并传递给负责渲染特定 version 哈希的组件。在这种情况下,它将是使用 KMeans 提取的五种有趣的颜色。

React 渲染器

提取的颜色被转换为在屏幕上动画化的垂直线。

此时,图像开始加载,加载,然后取代占位符。

改进领域

编码/解码

数据足够小,可能可以在 JSON 对象内部移动,而无需额外的 Base64 编码步骤。

占位符到完整图像的过渡

目前,当动画完成时,它将显示加载的任何内容。如果动画改为连接到图像的 onload 事件以实现更无缝的过渡,那就更好了。

生产准备

该项目探索了完成该过程的最小路径。没有考虑生产准备就绪。

轮到你了

如果你可以创造性地控制页面加载和被加载之间的时间 - 你会创造什么?告诉我!

通过 RSS 订阅

或者

订阅