Flutter中如何用BlurHash实现图片加载前占位效果?
实现BlurHash图片占位效果的完整方案
前置要求
- 确保API返回图片资源的同时,附带对应的BlurHash字符串(后端需用官方BlurHash库对原图编码生成该值)
- 前端引入BlurHash解码工具:可通过npm安装官方包,或直接用CDN引入
原生JavaScript实现步骤
1. 引入解码库
用npm安装:
npm install blurhash
或直接通过CDN引入:
<script src="https://unpkg.com/blurhash@2.0.5/dist/blurhash.min.js"></script>
2. 构建DOM结构
用容器包裹占位画布和真实图片,确保画布占满容器,图片加载完成后覆盖画布:
<div class="image-container" style="width: 400px; height: 300px; position: relative; overflow: hidden;"> <canvas id="blurhash-placeholder"></canvas> <img id="target-image" src="" alt="内容图片" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; display: none;"> </div>
3. 解码并渲染占位图
// 模拟API返回的数据 const apiResponse = { imageUrl: "https://example.com/your-real-image.jpg", blurHash: "LKO2?U%2Tw=w]~RBVZRi};RPxuwH" }; const canvas = document.getElementById('blurhash-placeholder'); const ctx = canvas.getContext('2d'); const targetImg = document.getElementById('target-image'); // 让画布尺寸匹配容器 canvas.width = canvas.offsetWidth; canvas.height = canvas.offsetHeight; // 解码BlurHash并绘制到画布 BlurHash.decode(apiResponse.blurHash, canvas.width, canvas.height).then(pixels => { const imageData = ctx.createImageData(canvas.width, canvas.height); imageData.data.set(pixels); ctx.putImageData(imageData, 0, 0); }); // 加载真实图片,完成后切换显示 targetImg.src = apiResponse.imageUrl; targetImg.onload = () => { targetImg.style.display = 'block'; canvas.style.display = 'none'; };
React框架实现步骤
1. 安装依赖
npm install blurhash react-blurhash
react-blurhash是官方封装的React组件,可简化开发流程
2. 组件代码示例
import { useState, useEffect } from 'react'; import { Blurhash } from 'react-blurhash'; const ImageWithBlurHash = ({ imageUrl, blurHash }) => { const [isImageLoaded, setIsImageLoaded] = useState(false); return ( <div style={{ position: 'relative', width: '400px', height: '300px' }}> {/* BlurHash占位组件 */} <Blurhash hash={blurHash} width={400} height={300} resolutionX={32} resolutionY={32} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }} /> {/* 真实图片 */} <img src={imageUrl} alt="内容图片" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', display: isImageLoaded ? 'block' : 'none' }} onLoad={() => setIsImageLoaded(true)} /> </div> ); }; // 组件使用示例 export default function App() { const [imageData, setImageData] = useState(null); useEffect(() => { // 模拟API请求 fetch('/api/get-image-data') .then(res => res.json()) .then(data => setImageData(data)); }, []); if (!imageData) return <div>加载中...</div>; return <ImageWithBlurHash imageUrl={imageData.imageUrl} blurHash={imageData.blurHash} />; }
关键注意事项
- 后端编码正确性:必须确保API返回的BlurHash字符串是对原图的正确编码,后端可使用对应语言的BlurHash库(如Python的
blurhash、Node.js的blurhash)生成 - 尺寸匹配:解码时的宽高需和图片实际显示尺寸一致,避免占位图拉伸变形
- 性能优化:批量加载图片时,可将BlurHash的分辨率(resolutionX/Y)设为16-32区间,减少解码计算量
内容的提问来源于stack exchange,提问作者Jigyasu Tanwar
相关产品推荐
相关产品推荐

