共用方式為


使用色彩矩陣變換單一色彩

GDI+ 提供了 ImageBitmap 類別,可用來儲存和操作影像。ImageBitmap 物件將每一個像素的色彩儲存成 32 位元的數字:各以 8 個位元來表示紅色、藍色和 Alpha。每一個元素的數字都是從 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) 開始,並套用下列變換:

  1. 將紅色元素加倍
  2. 將紅色、綠色和藍色元素加上 0.2

下列矩陣乘法將會依照列出來的順序執行成對的變換。

色彩矩陣的元素是根據先列後行的順序來編列索引 (以零起始)。例如,在矩陣 M 中第五列、第三行的項目便是以 M[4][2] 來表示。

5×5 識別矩陣 (顯示在下圖中) 的對角線都是 1,其他位置都是 0。如果您將色彩向量乘以識別矩陣,色彩向量不會變更。若要組成色彩變換矩陣,從識別矩陣開始是很方便的方式,然後做小幅度變更來產生想要的轉換。

如需矩陣和變換的詳細資訊,請參閱座標系統和變換

下列範例會使用全部為 (0.2, 0.0, 0.4, 1.0) 一個色彩的影像,並套用上一段所描述的變換。

Dim image = 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)
[C#]
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);

下圖左邊顯示的是原始的影像,右邊顯示的是變換的影像。

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

  1. 初始化 ColorMatrix 物件。
  2. 建立 ImageAttributes 物件,然後將 ColorMatrix 物件傳遞至 ImageAttributes 物件的 SetColorMatrix 方法。
  3. ImageAttributes 物件傳遞至 Graphics 物件的 DrawImage 方法。