次の方法で共有


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

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

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

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

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

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

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

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

5x1行列と5x5行列を乗算し、新しい5x1行列を作成する様子を示す図

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

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

5x5 の単位行列を示す 図で、左上から右下の対角線には 1 があり、それ以外の場所には 0 があります

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

次の例では、すべて 1 色 (0.2、0.0、0.4、1.0) の画像を取得し、前の段落で説明した変換を適用します。

Image            image(L"InputColor.bmp");
ImageAttributes  imageAttributes;
UINT             width = image.GetWidth();
UINT             height = image.GetHeight();

ColorMatrix colorMatrix = {
   2.0f, 0.0f, 0.0f, 0.0f, 0.0f,
   0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
   0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
   0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
   0.2f, 0.2f, 0.2f, 0.0f, 1.0f};
   
imageAttributes.SetColorMatrix(
   &colorMatrix, 
   ColorMatrixFlagsDefault,
   ColorAdjustTypeBitmap);
   
graphics.DrawImage(&image, 10, 10);

graphics.DrawImage(
   &image, 
   Rect(120, 10, width, height),  // destination rectangle 
   0, 0,        // upper-left corner of source rectangle 
   width,       // width of source rectangle
   height,      // height of source rectangle
   UnitPixel,
   &imageAttributes);

次の図は、左側の元の画像と右側の変換されたイメージを示しています。

暗い純色で塗りつぶされた四角形と、明るい純色で塗りつぶされた四角形を示す図

前の例のコードでは、次の手順を使用して色変更を実行します。

  1. ColorMatrix 構造体を初期化します。
  2. ImageAttributes オブジェクトを作成し、ColorMatrix 構造体のアドレスを、ImageAttributes オブジェクトの ImageAttributes::SetColorMatrix メソッドに渡します。
  3. ImageAttributes オブジェクトのアドレスを、Graphics オブジェクトの DrawImage メソッド メソッドに渡します。