다음을 통해 공유


색 매트릭스를 사용하여 단일 색 변환

Windows GDI+는 이미지를 저장하고 조작하기 위한 이미지비트맵 클래스를 제공합니다. 이미지비트맵 개체는 각 픽셀의 색을 32비트 숫자로 저장합니다. 빨간색, 녹색, 파랑 및 알파에 대해 각각 8비트입니다. 4개의 구성 요소는 각각 0에서 255까지의 숫자이며, 0은 농도가 없음을 나타내고, 255는 전체 농도를 나타냅니다. 알파 구성 요소는 색의 투명도를 지정합니다. 0은 완전히 투명하고 255는 완전히 불투명합니다.

색 벡터는 4 튜플의 폼(빨간색, 녹색, 파란색, 알파)입니다. 예를 들어, 색 벡터(0, 255, 0, 255)는 빨간색이나 파란색은 없지만, 녹색은 전체 농도를 가지는 불투명 색상을 나타냅니다.

색을 나타내는 또 다른 규칙은 최대 강도에 숫자 1을 사용하고 최소 강도의 경우 숫자 0을 사용합니다. 이 규칙을 사용하면 이전 단락에서 설명된 색이 벡터(0, 1, 0, 1)로 표현됩니다. GDI+은 색 변환을 수행할 때 1을 전체 농도로 하는 규칙을 사용합니다.

4×4 행렬을 곱하여 선형 변환(회전, 크기 조정 등)을 색 벡터에 적용할 수 있습니다. 그러나 4 ×4 행렬을 사용하여 변환(비선형)을 수행할 수는 없습니다. 각 색 벡터에 더미 다섯 번째 좌표(예: 숫자 1)를 추가하는 경우 5 ×5 행렬을 사용하여 선형 변환과 변환의 조합을 적용할 수 있습니다. 선형 변환과 변형으로 구성된 변환을 유사 변환이라고 합니다. 아핀 변환을 나타내는 5개의 ×5 행렬을 4공간 변환을 위한 동종 행렬이라고 합니다. 5개의 ×5 동종 행렬의 다섯 번째 행과 다섯 번째 열에 있는 요소는 1이어야 하며 다섯 번째 열의 다른 모든 항목은 0이어야 합니다.

예를 들어 색 (0.2, 0.0, 0.4, 1.0)으로 시작하고 다음 변환을 적용하려는 경우를 가정합니다.

  1. 빨간색 구성 요소 배가
  2. 빨간색, 녹색 및 파란색 구성 요소에 0.2 추가

다음 행렬 곱셈은 나열된 순서대로 변환 쌍을 수행합니다.

새 5x1 행렬을 만들기 위해 5x5 행렬을 곱한 숫자의 5x1 행렬을 보여 주는 일러스트레이션

색 행렬의 요소는 행과 열로 인덱싱됩니다(0부터). 예를 들어, 행렬 M의 다섯 번째 행과 세 번째 열에 있는 항목은 M[4][2]로 표시됩니다.

5개의 ×5 ID 행렬(다음 그림 참조)에는 대각선에 1이 있고 다른 곳에서는 0이 있습니다. 색 벡터를 ID 행렬에 곱할 경우, 색 벡터는 변경되지 않습니다. 색 변환의 행렬을 형성하는 편리한 방법은 ID 행렬로 시작하고 원하는 변환을 생성하는 작은 변경을 만드는 것입니다.

5x5 ID 행렬을 보여 주는 그림; 왼쪽 위에서 오른쪽 아래 대각선으로 1s, 다른 곳에서는 0s

행렬 및 변환에 대한 자세한 논의는 좌표계 및 변환을 참조하세요.

다음 예제에서는 모두 하나의 색(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 메서드 메서드에 전달합니다.