微信小程序不支持filter属性,包括grayscale(),因其渲染层禁用所有CSS滤镜;唯一可靠方案是Canvas像素级处理灰度图,App端需通过manifest.json配置plus.style.grayscale为true。

微信小程序里 filter: grayscale() 为什么没效果
因为微信小程序的渲染层压根不支持 filter,包括 grayscale()、blur() 等所有 CSS 滤镜,运行时会被静默忽略——不是你写错了,是平台禁用。
验证方法:在微信开发者工具中打开「调试器 → Elements」,选中图片元素,看 computed styles 里 filter 是否被划掉或根本没出现。
- 别在
<image>标签上写内联style="filter: grayscale(1)":uni-app 的<image>是原生组件,H5 下才转为<img>,小程序和 App 下都不认 - 别指望用
<view>包裹再加filter就能生效:小程序里<view>上的filter同样无效 - 想快速验证是否支持?在 H5 端打开同一页面,
filter能立刻看到效果,这就反向确认了是平台限制
Canvas 动态生成灰度图(微信小程序唯一可靠方案)
必须走 Canvas 像素级处理:先用 uni.getImageInfo 获取原始尺寸和路径,再用 uni.createCanvasContext 绘制、读取、灰度计算、写回、导出。
关键细节:
-
canvas宽高必须严格等于原图尺寸,否则拉伸失真;真机上建议乘uni.getSystemInfoSync().pixelRatio补偿 DPR - 灰度公式固定用
0.299 * R + 0.587 * G + 0.114 * B,不要用平均值或其它系数,否则偏色 -
canvas.draw()是异步的,必须等setTimeout或监听onReady后再调canvasToTempFilePath,否则返回空路径 - 大图(如 >1000px)遍历像素会明显卡顿,务必先用
uni.compressImage压缩到 800px 内再处理
H5 和 App 端的 filter 兼容写法
虽支持,但版本碎片严重:旧版 Android WebView 只认 grayscale(100%),不认 grayscale(1);iOS 一般 OK,但 App 端依赖系统 WebView 内核,Android 4.4 以下是雷区。
安全写法示例:
img.gray {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
/* 兜底:对完全不支持 filter 的老环境给个视觉提示 */
border: 1px solid #ccc;
}- 永远用百分比写法
grayscale(100%),别用小数grayscale(1)或grayscale(0.5) - 作用范围要选对:加在容器节点(如
<view class="gray-wrapper">)上,比单张<image>更可控 - 动态开关灰度,用
class切换,别用:style绑定内联样式,避免渲染异常
App 端灰度必须走 manifest.json 配置
App 端(iOS/Android)的原生渲染层不识别任何 CSS filter,哪怕写在 <html> 或 <body> 上也无效——这是底层限制,不是前端能绕过的。
正确路径只有一条:
- 在
manifest.json中写入:"plus": { "style": { "grayscale": true } } -
grayscale必须是布尔值true,不能是字符串"true"或数字1 - 改完必须「重新云打包」或「重做自定义基座」,热更新、HMR、本地调试都不会触发该配置
- 注意:这个灰度是全局的,会影响整个 App 界面,但原生组件(如状态栏、picker、camera)仍为彩色,前端无法覆盖
跨平台项目里,最容易被忽略的是:H5 和小程序用 Canvas 或 CSS,App 却必须切到 manifest 配置——三端逻辑完全隔离,没法共用一套代码。


















