閱讀英文

共用方式為


如何:使用色彩矩陣轉換單一色彩

GDI+ 提供用來儲存和操作影像的 ImageBitmap 類別。 ImageBitmap 物件會將每個像素的色彩儲存為 32 位元數字:紅色、綠色、藍色和 Alpha 各有 8 位元。 這四個元件中的每一個都是從 0 到 255 的數字,0 代表沒有強度,而 255 代表完整強度。 Alpha 元件會指定色彩的透明度:0 為完全透明,而 255 則完全不透明。

色彩向量是 4 Tuple 格式 (紅色、綠色、藍色、Alpha)。 例如,色彩向量 (0, 255, 0, 255) 代表不透明色彩,沒有紅色或藍色,但具有完整強度的綠色。

用於表示色彩的另一個慣例會使用數字 1 表示完整強度。 使用該慣例時,前一段所述的色彩會以向量表示 (0, 1, 0, 1)。 GDI+ 會在執行色彩轉換時,使用 1 的慣例作為完整強度。

您可以將線性轉換 (旋轉、縮放等) 套用至色彩向量,方法是將色彩向量乘以 4x4 矩陣。 不過,您無法使用 4x4 矩陣來執行轉換 (非線性)。 如果您將虛擬第五個座標 (例如數字 1) 新增至每個色彩向量,您可以使用 5x5 矩陣來套用線性轉換和轉譯的任何組合。 由線性轉換後面接著轉譯所組成的轉換稱為仿射轉換。

例如,假設您想要從色彩 (0.2, 0.0, 0.4, 1.0) 開始,並套用下列轉換:

  1. 將紅色元件加倍

  2. 為紅色、綠色和藍色元件加 0.2

下列矩陣乘法會依照列出的順序執行轉換對組。

轉換乘法矩陣的螢幕擷取畫面。

色彩矩陣的元素會依資料列然後資料行編製索引 (以零為起始)。 例如,矩陣 M 的第五個資料列和第三個資料行的項目是以 M[4][2] 表示。

5x5 單位矩陣 (如下圖所示) 在對角線上有 1,其他位置上有 0。 如果您將色彩向量乘以單位矩陣,則色彩向量不會變更。 形成色彩轉換矩陣的便利方式,就是從單位矩陣開始,並進行產生所需轉換的小型變更。

用於色彩轉換的 5x5 單位矩陣的螢幕擷取畫面。

如需矩陣和轉換的更詳細討論,請參閱座標系統和轉換

範例

下列範例會採用全為一種色彩的影像 (0.2, 0.0, 0.4, 1.0),並套用前一段所述的轉換。

下圖顯示左側的原始影像和右側的已轉換影像。

左側為紫色方塊和右側為紫紅色方塊。

下列範例中的程式碼會使用下列步驟來執行重新著色:

  1. 初始化 ColorMatrix 物件。

  2. 建立 ImageAttributes 物件,並將 ColorMatrix 物件傳遞至 SetColorMatrix 物件的 ImageAttributes 方法。

  3. 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 Forms 使用而設計,且其需要 PaintEventArgse,這是 Paint 事件處理常式的參數。

另請參閱