可可图片编辑 HarmonyOS(5)滤镜效果 
前言 
可可图片编辑也实现了滤镜效果,主要是利用 Image组件的 colorFilter 属性实现。


滤镜的关键属性 colorFilter 
colorFilter 的主要作用是给图像设置颜色滤镜效果。
其核心原理是使用一个 4x5 的颜色矩阵 对图片的每个像素颜色(RGBA)进行数学变换,从而得到一个新的颜色值。
参数类型:
colorFilter(value: ColorFilter | DrawingColorFilter)它接受两种类型的参数:
- ColorFilter: ArkUI 自带的颜色滤镜对象,主要通过传递一个 4x5 的矩阵数组来使用。
- DrawingColorFilter: 来自- @kit.ArkGraphics2D- 绘图模块的、功能更丰富的颜色滤镜对象,提供了多种静态创建方法(如混合模式、矩阵、光照等)。 
使用方法 1 :使用 ColorFilter 和 4x5 颜色矩阵 
这是最基础和最灵活的方式。你需要构造一个包含 20 个数字的数组来表示一个 4x5 的矩阵。

1. 矩阵计算规则 
矩阵结构如下,它会对每个像素的原始颜色 [R, G, B, A] 进行运算:
输出颜色 [R', G', B', A'] 的计算公式为:
R' = r1*R + r2*G + r3*B + r4*A + r5 * 255
G' = g1*R + g2*G + g3*B + g4*A + g5 * 255
B' = b1*R + b2*G + b3*B + b4*A + b5 * 255
A' = a1*R + a2*G + a3*B + a4*A + a5 * 255重要提示:计算时,原始颜色值(R,G,B,A)需要先归一化(Normalize)到 [0.0, 1.0] 的浮点数范围(1.0 对应 255)。
示例代码:
后续的效果都可以在当前示例代码上进行修改
@Entry
@Component
struct Index {
  private grayMatrix: number[] =
    // 冷色调 (增强蓝色和青色)
    [
      0.9, 0, 0, 0, 0, // 略微减弱红色
      0, 1.0, 0, 0, 0,
      0, 0, 1.2, 0, 0, // 增强蓝色
      0, 0, 0, 1, 0
    ]
  private grayFilter: ColorFilter = new ColorFilter(this.grayMatrix);
  build() {
    Column({ space: 20 }) {
      // 原始图片
      Image($r('app.media.startIcon'))
        .width(100)
        .height(100)
      // 使用 ColorFilter 矩阵
      Image($r('app.media.app_icon'))
        .width(100)
        .height(100)
        .colorFilter(this.grayFilter)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}2. 常用矩阵示例 
a) 原图效果(单位矩阵) 保持图片原有色彩,不对其做任何改变。

// 单位矩阵
[1, 0, 0, 0, 0,
 0, 1, 0, 0, 0,
 0, 0, 1, 0, 0,
 0, 0, 0, 1, 0]b) 灰度效果 将图片转换为黑白灰度图。常见的权重公式是 0.299*R + 0.587*G + 0.114*B。

[0.299, 0.587, 0.114, 0, 0,
 0.299, 0.587, 0.114, 0, 0,
 0.299, 0.587, 0.114, 0, 0,
 0,     0,     0,     1, 0]c) 颜色反转(负片效果) 将每个颜色通道取反。

[-1, 0, 0, 0, 1,
  0,-1, 0, 0, 1,
  0, 0,-1, 0, 1,
  0, 0, 0, 1, 0]d) 纯色着色(文档中的核心方案) 忽略原图颜色,将其渲染为指定的目标颜色(例如 #4f0f48db)。

- 将 RGB 通道的前四列系数设为 0,完全丢弃原图颜色信息。
- 将 RGB 通道的第五列设置为目标颜色归一化后的。
- Alpha 通道通常保持不变。
假设目标色为 #4f0f48db,其归一化后的值为:
- A = 0.31 (79/255)
- R = 0.06 (15/255)
- G = 0.28 (72/255)
- B = 0.86 (219/255)
对应的矩阵为:
[0, 0, 0, 0, 0.06, // R' = 0 + 0.06*255
 0, 0, 0, 0, 0.28, // G' = 0 + 0.28*255
 0, 0, 0, 0, 0.86, // B' = 0 + 0.86*255
 0, 0, 0, 1, 0]    // A' = Original Ae) 棕褐色怀旧效果 (Sepia) ,这是一种经典的老照片效果,为图像添加温暖的棕褐色调。

[
  0.393, 0.769, 0.189, 0, 0,
  0.349, 0.686, 0.168, 0, 0,
  0.272, 0.534, 0.131, 0, 0,
  0,     0,     0,     1, 0
]f) 亮度调节,整体提升或降低图像的亮度。

// 调整 brightness 值,范围通常在 -1.0 到 1.0 之间
// 正数变亮,负数变暗
const brightness = 0.3; // 增加30%的亮度
[
  1, 0, 0, 0, brightness,
  0, 1, 0, 0, brightness,
  0, 0, 1, 0, brightness,
  0, 0, 0, 1, 0
]g) 冷色调/暖色调 通过微调不同颜色通道的增益,营造冷暖感觉.

// 暖色调 (增强红色和黄色)
[
  1.2, 0, 0, 0, 0,
  0, 1.1, 0, 0, 0,
  0, 0, 0.9, 0, 0, // 略微减弱蓝色
  0, 0, 0, 1, 0
]
// 冷色调 (增强蓝色和青色)
[
  0.9, 0, 0, 0, 0, // 略微减弱红色
  0, 1.0, 0, 0, 0,
  0, 0, 1.2, 0, 0, // 增强蓝色
  0, 0, 0, 1, 0
]使用方法 2 :使用 DrawingColorFilter(推荐,更简单) 
通过 '@kit.ArkGraphics2D' 模块提供的多种静态方法创建滤镜,这种方式通常更简洁易懂。
1. 导入模块 
import { drawing } from '@kit.ArkGraphics2D';2. 使用预置方法创建滤镜 
a) 创建混合模式滤镜 (createBlendModeColorFilter)
使用指定的颜色和混合模式(如 BlendMode.SRC_IN)进行混合,非常适合着色。

import { drawing } from '@kit.ArkGraphics2D';
// 创建一个红色的,采用 SRC_IN 混合模式的滤镜
// SRC_IN: 最终颜色由源颜色(这里指红色)和目标区域的Alpha共同决定,常用于着色
let colorFilter = drawing.ColorFilter.createBlendModeColorFilter(
  {
    alpha: 255,
    red: 255,
    green: 0,
    blue: 0
  }, // 颜色对象,这里是红色
  drawing.BlendMode.SRC_IN
);
@Entry
@Component
struct Index {
  build() {
    Column({ space: 20 }) {
      // 原始图片
      Image($r('app.media.startIcon'))
        .width(100)
        .height(100)
      Image($r('app.media.startIcon'))
        .width(100)
        .height(100)
        .colorFilter(colorFilter)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}b) 直接通过矩阵创建 (createMatrixColorFilter)
与原生 ColorFilter 类似,但使用 drawing 模块的接口。

import { drawing } from '@kit.ArkGraphics2D';
let matrix = [
  0.299, 0.587, 0.114, 0, 0,
  0.299, 0.587, 0.114, 0, 0,
  0.299, 0.587, 0.114, 0, 0,
  0, 0, 0, 1, 0
];
let grayFilter = drawing.ColorFilter.createMatrixColorFilter(matrix);
@Entry
@Component
struct Index {
  build() {
    Column({ space: 20 }) {
      // 原始图片
      Image($r('app.media.startIcon'))
        .width(100)
        .height(100)
      Image($r('app.media.startIcon'))
        .width(100)
        .height(100)
        .colorFilter(grayFilter)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}注意事项 
性能:颜色滤镜的运算发生在渲染时,对于大图或频繁操作,可能会有性能开销。建议对处理后的结果进行缓存。
Alpha 通道:在处理透明度时务必小心,错误的矩阵设置可能导致图片完全透明或出现非预期的半透明效果。
对于简单的颜色覆盖/着色,优先推荐使用 drawing.ColorFilter.createBlendModeColorFilter,它的代码更简洁,意图更
清晰。对于复杂的颜色变换(如复古、色调分离等),再考虑使用自定义矩阵。
以往文章 
- 我的iMaHarmonyOS 知识库接入 鸿蒙6 API20 新特性了 - https://mp.weixin.qq.com/s/YsbFQyi5PsndpRUaA9h_dA?token=830743671&lang=zh_CN 
- 鸿蒙创新赛 HarmonyOS 6.0.0(20) 关键特性汇总 
- 可可图片编辑 HarmonyOS(4)图片裁剪-canvas 
- 可可图片编辑 HarmonyOS(3)应用间分享图片 
近期活动 
最近想要想要考取 HarmonyOS 基础或者高级证书,或者快要获取的同学都可以点击这个链接,加入我的班级,考取成功有机会获得鸿蒙礼盒一份。

联系我 
可以加我微信,带你了解更多HarmonyOS相关的资讯。
