使用Blurhash和mdui实现动态主题色与模糊预览
在现代Web开发中,用户体验的提升往往伴随着细节的优化。Blurhash 是一个用于生成和解码模糊哈希的库,能够实现图片的模糊预览效果。而 mdui 为我们提供了基于 Material Design 3 (Material You) 的前端框架,包含丰富的组件和样式。在这篇博文中,我们将结合Blurhash和mdui,实现一个根据背景图动态设置主题色的页面,并优化图片加载性能。
目标
我们希望在页面底部附上一张背景图,并使用这张背景图的主色调作为整个页面的主题色。
预处理图片生成Blurhash并通过随机图api直接提供
为了避免在页面加载时的计算开销,我们可以预先生成每张图片的Blurhash,并存储在一个JSON文件中。
下面的Python脚本可以批量处理图片并生成Blurhash:
import concurrent.futures
import os
import json
import logging
from PIL import Image
from blurhash import encode
logging.basicConfig(level=logging.INFO)
current_path = os.path.abspath(os.path.dirname(__file__))
def encode_file(file):
logging.info(f'Encoding {file} to blurhash')
image = Image.open(os.path.join(current_path, file))
blurhash = encode(image, x_components=4, y_components=3)
return file, blurhash
current_files = [f for f in os.listdir(current_path) if f.endswith(('jpg', 'png', 'jpeg'))]
blurhashes = {}
with concurrent.futures.ThreadPoolExecutor() as executor:
future_to_file = {executor.submit(encode_file, file): file for file in current_files}
for future in concurrent.futures.as_completed(future_to_file):
file = future_to_file[future]
try:
file, blurhash = future.result()
blurhashes[file] = blurhash
except Exception as exc:
logging.error('%r generated an exception: %s' % (file, exc))
with open('blurhash.json', 'w') as f:
json.dump(blurhashes, f)
那么我们后端就可以通过读取这个json文件来获取到图片对应的blurhash值,并与图片一起提供
提供的数据大概如下
json
{
"code": "200",
"image": "https://cdn.tnxg.top/images/wallpaper/5.jpg",
"blurhash": "LcI~*}r=TJS$~VX8S2b^?HW;wIoe"
}
设置背景图和主题色
我们这时候就已经拥有了图片的url以及对应的模糊哈希。
我们这时就能将模糊哈希转换为base64格式的图片
const blurredImage = (blurhash) => {
if (!blurhash) return '';
const pixels = decode(blurhash, 32, 32);
const canvas = document.createElement('canvas');
canvas.width = 32;
canvas.height = 32;
const ctx = canvas.getContext('2d');
const imageData = ctx.createImageData(32, 32);
imageData.data.set(pixels);
ctx.putImageData(imageData, 0, 0);
return canvas.toDataURL();
};
然后我们就能够将base64图片新建一个image对象,并获取其主题色
因为是原图的模糊哈希转换来的图片,主体色调应该差不太多,所以我们可以直接使用这个颜色作为主题色
const blurredImageData = blurredImage(data.blurhash);
const ColorImage = new Image();
ColorImage.src = blurredImageData;
getColorFromImage(ColorImage)
.then(color => {
setColorScheme(color);
console.log('Color scheme set.' + color);
})
生成出的base64模糊图也可以用来当做卡片的背景,保持背景和卡片的色调显得相得益彰
关于Blurhash的传递我们可以使用状态管理Pinia直接将转换过后的base64图片存储在全局状态中,这样就不用每次都重新计算了
最终效果
通过以上步骤,我们实现了在页面加载时先显示模糊预览图,并根据其主色调动态设置主题色。当高清背景图加载完成后,替换掉模糊预览图,提升了用户体验和页面性能。
以下是最终效果的示例:
希望这篇博文能帮助你更好地理解和使用Blurhash与mdui来提升Web应用的用户体验。如果你有任何问题或建议,欢迎在评论区留言。