如何:使用色彩矩陣轉換單一色彩
GDI+ 提供 Image 和 Bitmap 類別來儲存和操作影像。 Image 和 Bitmap 物件會將每個圖元的色彩儲存為 32 位數位:紅色、綠色、藍色和 Alpha 各有 8 位。 這四個元件中的每一個都是從 0 到 255 的數位,0 代表沒有強度,255 代表完整強度。 Alpha 元件會指定色彩的透明度:0 是完全透明的,而 255 則完全不透明。
色彩向量是 4 元組的形式(紅色、綠色、藍色、Alpha)。 例如,色彩向量 (0, 255, 0, 255) 代表不透明色彩,沒有紅色或藍色,但具有全濃度的綠色。
代表色彩的另一個慣例會使用數位 1 表示完整強度。 使用該慣例時,前一段所述的色彩會以向量表示(0、1、0、1)。 GDI+ 會在執行色彩轉換時,使用 1 的慣例作為完整強度。
您可以將線性轉換(旋轉、縮放等)套用至色彩向量,方法是將色彩向量乘以 4×4 矩陣。 不過,您無法使用 4×4 矩陣來執行翻譯(非線性)。 如果您將虛擬第五個座標(例如數位 1)新增至每個色彩向量,您可以使用 5×5 矩陣來套用線性轉換和轉譯的任何組合。 由線性轉換所組成的轉換,後面接著轉譯稱為仿射轉換。
例如,假設您想要從色彩 (0.2、 0.0、 0.4、 1.0) 開始,並套用下列轉換:
將紅色元件加倍
將 0.2 新增至紅色、綠色和藍色元件
下列矩陣乘法會依照列出的循序執行轉換組。
色彩矩陣的專案會依資料列和資料行編制索引(以零起始)。 例如,矩陣 M
第五列和第三欄的專案是以 表示 M[4][2]
。
5×5 身分識別矩陣(如下圖所示)在對角線上有 1 個,其他地方有 0 個。 如果您將色彩向量乘以識別矩陣,則色彩向量不會變更。 形成色彩轉換矩陣的便利方式,就是從識別矩陣開始,並進行產生所需轉換的小型變更。
如需矩陣和轉換的更詳細討論,請參閱 座標系統和轉換 。
範例
下列範例會採用全部一種色彩的影像(0.2、0.0、0.4、1.0),並套用上述段落中所述的轉換。
下圖顯示左側的原始影像和右側已轉換的影像。
下列範例中的程式碼會使用下列步驟來執行重新著色:
ColorMatrix初始化 物件。
建立 ImageAttributes 物件,並將 物件傳遞 ColorMatrix 至 SetColorMatrix 物件的 方法 ImageAttributes 。
將 ImageAttributes 物件傳遞至 DrawImage 物件的 方法 Graphics 。
Image image = new Bitmap("InputColor.bmp");
ImageAttributes imageAttributes = new ImageAttributes();
int width = image.Width;
int height = image.Height;
float[][] colorMatrixElements = {
new float[] {2, 0, 0, 0, 0}, // red scaling factor of 2
new float[] {0, 1, 0, 0, 0}, // green scaling factor of 1
new float[] {0, 0, 1, 0, 0}, // blue scaling factor of 1
new float[] {0, 0, 0, 1, 0}, // alpha scaling factor of 1
new float[] {.2f, .2f, .2f, 0, 1}}; // three translations of 0.2
ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);
imageAttributes.SetColorMatrix(
colorMatrix,
ColorMatrixFlag.Default,
ColorAdjustType.Bitmap);
e.Graphics.DrawImage(image, 10, 10);
e.Graphics.DrawImage(
image,
new Rectangle(120, 10, width, height), // destination rectangle
0, 0, // upper-left corner of source rectangle
width, // width of source rectangle
height, // height of source rectangle
GraphicsUnit.Pixel,
imageAttributes);
Dim image As New Bitmap("InputColor.bmp")
Dim imageAttributes As New ImageAttributes()
Dim width As Integer = image.Width
Dim height As Integer = image.Height
' The following matrix consists of the following transformations:
' red scaling factor of 2
' green scaling factor of 1
' blue scaling factor of 1
' alpha scaling factor of 1
' three translations of 0.2
Dim colorMatrixElements As Single()() = { _
New Single() {2, 0, 0, 0, 0}, _
New Single() {0, 1, 0, 0, 0}, _
New Single() {0, 0, 1, 0, 0}, _
New Single() {0, 0, 0, 1, 0}, _
New Single() {0.2F, 0.2F, 0.2F, 0, 1}}
Dim colorMatrix As New ColorMatrix(colorMatrixElements)
imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap)
e.Graphics.DrawImage(image, 10, 10)
e.Graphics.DrawImage( _
image, _
New Rectangle(120, 10, width, height), _
0, _
0, _
width, _
height, _
GraphicsUnit.Pixel, _
imageAttributes)
編譯程式碼
上述範例是為了搭配 Windows Form 使用而設計,且其需要 PaintEventArgse
,這是 Paint 事件處理常式的參數。
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應