カラー マトリックスを使用した単色の変換
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) の色で開始し、次の変換を適用したとします。
- 赤の要素を 2 倍にする
- 赤、緑、および青の要素に 0.2 を加算する
次の行列の乗算では、変換のペアが列挙順に実行されます。
カラー行列の要素には、行、列の順でインデックス (0 から開始) が付けられます。 たとえば、行列 M の 5 行目の3 列目にあるエントリは、M[4][2] で示されます。
5 ×5 の ID マトリックス (次の図に示します) には、対角線に 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);
次の図は、左側に元の画像、右側に変換後の画像を示したものです。
前の例のコードでは、次の手順を使用して色変更を実行します。
- ColorMatrix 構造体を初期化します。
- ImageAttributes オブジェクトを作成し、ColorMatrix 構造体のアドレスを ImageAttributes オブジェクトの ImageAttributes::SetColorMatrix メソッドに渡します。
- ImageAttributes オブジェクトのアドレスを Graphics オブジェクトの DrawImage Methods メソッドに渡します。