可可圖片編輯 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*2550, 0, 0, 0, 0.28, // G' = 0 + 0.28*2550, 0, 0, 0, 0.86, // B' = 0 + 0.86*2550, 0, 0, 1, 0] // A' = Original A
e) 棕褐色懷舊效果 (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) 關鍵特性匯總
https://mp.weixin.qq.com/s/ERmgSAIT8B8njFqtyPx9IQ
-
可可圖片編輯 HarmonyOS(4)圖片裁剪-canvas
https://mp.weixin.qq.com/s/2M3f_LNnt0YRo0qEnCnqpA
-
可可圖片編輯 HarmonyOS(3)應用間分享圖片
https://mp.weixin.qq.com/s/n8kkdougB4lqDHjYC7co8g