次の方法で共有


方法: カラー マトリックスを使用して単一の色を変換する

GDI+ には、イメージを格納および操作するための Image クラスと Bitmap クラスが用意されています。 Image および Bitmap オブジェクトは、各ピクセルの色を 32 ビットの数値として格納します。赤、緑、青、アルファの場合はそれぞれ 8 ビットです。 4 つの各コンポーネントは 0 から 255 までの数値であり、0 は強度を表せず、255 は完全な強度を表します。 アルファ コンポーネントは、色の透明度を指定します。0 は完全に透明で、255 は完全に不透明です。

カラー ベクターは、フォームの 4 タプル (赤、緑、青、アルファ) です。 たとえば、カラー ベクター (0、255、0、255) は、赤や青を持たないが、完全な強度で緑を持つ不透明な色を表します。

色を表すもう 1 つの規則では、完全な強度に 1 を使用します。 この規則を使用すると、前の段落で説明した色がベクトル (0、1、0、1) で表されます。 GDI+ は、色変換を実行するときに、1 の規則を完全な強度として使用します。

カラー ベクトルに 4×4 行列を乗算することで、線形変換 (回転、スケーリングなど) をカラー ベクトルに適用できます。 ただし、4×4 行列を使用して平行移動 (非線形) を実行することはできません。 各カラー ベクトルにダミーの 5 番目の座標 (例: 数値 1) を追加する場合は、5×5 行列を使用して線形変換と平行移動の任意の組み合わせを適用できます。 線形変換とそれに続く変換で構成される変換は、アフィン変換と呼ばれます。

たとえば、色 (0.2、0.0、0.4、1.0) から始めて、次の変換を適用するとします。

  1. 赤いコンポーネントを 2 倍に

  2. 赤、緑、青の各コンポーネントに 0.2 を追加する

次の行列乗算では、一覧の順序で変換のペアが実行されます。

変換乗算行列のスクリーンショット。

カラー マトリックスの要素は、行および列ごとにインデックスが作成されます (0 から始まります)。 たとえば、マトリックス M の 5 行目と 3 列目のエントリは、 M[4][2]で示されます。

5×5 の ID マトリックス (次の図に示します) は、対角線上に 1、他の場所では 0 を持っています。 色ベクトルに同一行列を乗算しても、色ベクトルは変化しません。 色変換の行列を形成する便利な方法は、ID 行列から始めて、目的の変換を生成する小さな変更を行う方法です。

色変換用の 5 x 5 の ID マトリックスのスクリーンショット。

行列と変換の詳細については、「座標系と変換の」を参照してください。

次の例では、すべて 1 色 (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 フォームで使用できるように設計されており、PaintEventArgs イベント ハンドラーのパラメーターである ePaintが必要です。

こちらも参照ください