小程序端无法用filter: blur()实现背景图高斯模糊,必须用Canvas手动采样+重绘,且需先下载网络图至本地临时路径再处理,核心是降采样+上采样模拟模糊感,性能远优于纯JS高斯算法。

小程序端无法用 filter: blur() 实现背景图高斯模糊,必须用 Canvas 手动采样+重绘,且不能直接对网络图操作——这是最常踩的坑。
微信/支付宝小程序:Canvas 块状采样模拟马赛克式模糊
小程序不支持 filter,也不允许直接读取网络图片像素(uni.canvasGetImageData 仅支持本地路径),所以得先下载图再处理。核心不是高斯卷积,而是「降采样 + 上采样」模拟视觉模糊感,性能远优于纯 JS 高斯算法。
- 必须用
uni.downloadFile把网络图存成本地临时路径,否则ctx.drawImage会失败 - 推荐用固定块大小(如
8x8)做均值采样:先缩小画布 → 填充像素 → 再放大回原尺寸,比逐像素计算快 10 倍以上 - 注意 canvas 宽高需与目标容器一致,否则缩放后边缘留白;建议用
uni.getSystemInfoSync().windowWidth动态算尺寸 - 微信小程序 Canvas 2D API 在 iOS 旧版本(如 iOS 14.5)存在
drawImage异步延迟问题,需加setTimeout等待 16ms 再调ctx.draw
示例关键片段:
const res = await uni.downloadFile({ url: this.bgUrl });
if (res.tempFilePath) {
const ctx = uni.createCanvasContext('bg-canvas', this);
ctx.drawImage(res.tempFilePath, 0, 0, width, height);
ctx.draw(false, () => {
uni.canvasGetImageData({
canvasId: 'bg-canvas',
x: 0, y: 0, width, height,
success: ({ data }) => {
const blurred = this.downsampleUpSample(data, width, height, 8); // 8px 块
uni.canvasPutImageData({
canvasId: 'bg-canvas',
data: blurred,
x: 0, y: 0, width, height
});
}
});
});
}
H5 端可直接用 stackblur-canvas,但别在小程序里引它
stackblur-canvas 是为浏览器 canvas 设计的轻量高斯模糊库,在 H5 端开箱即用;但它依赖 OffscreenCanvas 和完整 ImageData API,在小程序环境会报 canvas.getContext is not a function 或直接静默失败。
- H5 端引入方式:
import stackBlur from 'stackblur-canvas',然后stackBlur(imageElement, 0, 0, width, height, radius) - 千万别在
platform === 'mp-weixin'分支里 import 它——打包时不会报错,运行时才崩 - radius 建议控制在
2–8之间;超过 10 小程序 Canvas 绘制耗时会陡增,尤其安卓低端机
App 端(nvue)必须走原生插件,JS 模糊等于卡死
nvue 渲染层不支持 CSS filter,Canvas 性能比小程序还差(尤其 Android),一张 1080p 图 JS 高斯模糊可能耗时 800ms+,滚动时掉帧明显。
- iOS 推荐用
ios-blur-view插件,直接调用UIVisualEffectView,支持extraLight/light/dark三种系统级毛玻璃效果 - Android 可用
android-blur插件,底层调用 RenderScript,比纯 Java 实现快 3–5 倍 - 插件需在
manifest.json → app-plus → nvueStyle开启"nvueStyle": "native",否则无效 - 切记:nvue 页面中
<image></image>无法设background-image,模糊背景必须用<view></view>+ 原生插件 overlay 实现
跨平台统一写法:用条件编译 + 占位图兜底
不同平台渲染逻辑差异太大,硬写一套通用代码只会让三端都出问题。必须用 #ifdef 显式分路径,且给每种平台配 fallback。
- H5:用
filter: blur(6px)+transform: scale(1.05)防边缘空白 - 小程序:Canvas 处理完生成临时路径,用
<image :src="blurredPath"></image>替换原图 - App:nvue 中用
<blur-view effect="light"></blur-view>(插件组件),并监听@ready事件确保渲染完成 - 所有平台都加 loading 占位图,Canvas 处理耗时 >300ms 时显示骨架屏,避免白屏
真正难的不是怎么模糊,而是怎么让模糊不拖慢首屏、不炸内存、不在某台安卓机上突然变色——这些细节只在真机连测三天后才会暴露出来。


















