You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:01:17