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

Flutter中如何给图片文件直接应用ColorFilter矩阵并保存到本地

Flutter 应用ColorFilter矩阵到图片并保存本地实现方案

前置依赖

首先添加第三方图像像素处理库image到pubspec.yaml,无需依赖Widget渲染即可直接操作图像数据:

dependencies:
  flutter:
    sdk: flutter
  image: ^4.0.17 # 可替换为最新稳定版

核心实现

首先导入必要的包:

import 'dart:io';
import 'package:image/image.dart' as img;
import 'package:flutter/painting.dart';

通过扩展方法实现你需要的调用形式,矩阵计算逻辑和Flutter官方ColorFilter渲染规则完全一致,效果和ColorFiltered组件展示效果无差异:

extension ColorFilterFile on File {
  Future<File> addColorFilter(ColorFilter filter) async {
    // 提取ColorFilter的20位矩阵参数
    final matrix = (filter as ColorFilterMatrix).matrix;
    // 读取并解码原图片文件
    final originBytes = await readAsBytes();
    final originImage = img.decodeImage(originBytes);
    if (originImage == null) return this;

    final filteredImage = img.Image.from(originImage);
    // 遍历所有像素应用滤镜变换
    for (int y = 0; y < filteredImage.height; y++) {
      for (int x = 0; x < filteredImage.width; x++) {
        final pixel = filteredImage.getPixel(x, y);
        final r = pixel.r.toDouble();
        final g = pixel.g.toDouble();
        final b = pixel.b.toDouble();
        final a = pixel.a.toDouble();

        // 按矩阵规则计算新的RGBA值
        double newR = matrix[0]*r + matrix[1]*g + matrix[2]*b + matrix[3]*a + matrix[4];
        double newG = matrix[5]*r + matrix[6]*g + matrix[7]*b + matrix[8]*a + matrix[9];
        double newB = matrix[10]*r + matrix[11]*g + matrix[12]*b + matrix[13]*a + matrix[14];
        double newA = matrix[15]*r + matrix[16]*g + matrix[17]*b + matrix[18]*a + matrix[19];

        // 数值范围限制在有效区间0-255
        newR = newR.clamp(0, 255);
        newG = newG.clamp(0, 255);
        newB = newB.clamp(0, 255);
        newA = newA.clamp(0, 255);

        // 替换为滤镜后的像素
        filteredImage.setPixelRgba(x, y, newR.toInt(), newG.toInt(), newB.toInt(), newA.toInt());
      }
    }

    // 编码为图片文件,需要保留透明通道可替换为encodePng
    final filteredBytes = img.encodeJpg(filteredImage);
    // 自定义存储路径,此处默认存在原文件同级目录
    final newFile = File('${parent.path}/filtered_${uri.pathSegments.last}');
    await newFile.writeAsBytes(filteredBytes);
    return newFile;
  }
}

如果需要直接得到Image组件的扩展,可额外添加以下实现:

extension ColorFilterImage on Image {
  Future<Image> addColorFilter(ColorFilter filter) async {
    final file = (this.image as FileImage).file;
    final filteredFile = await file.addColorFilter(filter);
    return Image.file(filteredFile);
  }
}

调用示例

完全符合你预期的调用形式:

// 直接对文件应用滤镜得到新文件
File colorFilterFile = await _sampleFile.addColorFilter(ColorFilter.matrix(filter[2]));

// 对Image组件应用滤镜得到新的Image组件
Image image = Image.file(_sampleFile);
Image colorFilterImage = await image.addColorFilter(ColorFilter.matrix(filter[2]));

注意事项

  • 处理高分辨率大图片时建议放到Isolate中执行,避免阻塞主线程造成卡顿
  • 存储格式可根据需求调整,需要透明通道时将编码方法替换为img.encodePng即可

内容的提问来源于stack exchange,提问作者Vora Ravi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:45:00