次の方法で共有


カラー マトリックスを使用した単色の変換

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 行列を乗算した数値の 5 x 1 行列を示す図

カラー行列の要素には、行、列の順でインデックス (0 から開始) が付けられます。 たとえば、行列 M の 5 行目の3 列目にあるエントリは、M[4][2] で示されます。

5 ×5 の ID マトリックス (次の図に示します) には、対角線に 1 と 0 が表示されます。 この単位行列でカラー ベクターを乗算した場合、カラー ベクターに変化は起こりません。 色変換の行列を形成する際には、最初に単位行列を作り、その後小さな変更を加えて必要な変換を行うやり方が便利です。

5 x 5 の ID マトリックスを示す図。左上から右下の対角線に 1s、他の場所では 0s

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

次の例では、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 Methods メソッドに渡します。