Nasıl yapılır: Tek Bir Rengi Dönüştürmek için Renk Matrisi Kullanma

GDI+, ImageBitmap görüntüleri depolamak ve işlemek için ve sınıflarını sağlar. Image ve Bitmap nesneler her bir pikselin rengini 32 bitlik bir sayı olarak depolar: her biri kırmızı, yeşil, mavi ve Alfa için 8 bittir. Dört bileşenin her biri, 0 ile 255 arasında bir sayıdır ve tam yoğunluğu temsil eden 255 ' i temsil eder. Alfa bileşeni rengin saydamlığını belirtir: 0 tamamen saydamdır ve 255 tamamen donuk olur.

Renkli bir vektör, formun (kırmızı, yeşil, mavi, alfa) 4 tanımlama grubu olur. Örneğin, (0, 255, 0, 255) renk vektörü, kırmızı veya mavi olmayan donuk bir rengi temsil eder, ancak tam yoğunluğu üzerinde yeşil renkte olur.

Renkleri temsil eden başka bir kural, tam yoğunluk için 1 sayısını kullanır. Bu kuralı kullanarak, önceki paragrafta açıklanan renk vector (0, 1, 0, 1) tarafından temsil edilir. GDI+, renk dönüştürmeleri gerçekleştirdiğinde 1 kuralını tam yoğunluk olarak kullanır.

Renk vektörlerini 4 × 4 matris ile çarparak renk vektörlerine doğrusal dönüştürmeler (döndürme, ölçekleme ve benzeri) uygulayabilirsiniz. Ancak, bir çeviri gerçekleştirmek için 4 × 4 matris kullanamazsınız (doğrusal olmayan). Renk vektörlerinin her birine bir kukla beşinci koordinat (örneğin, 1) eklerseniz, doğrusal dönüştürmelerin ve çevirilerin birleşimini uygulamak için 5 × 5 matrisi kullanabilirsiniz. Doğrusal bir dönüşümden ve ardından bir çeviri tarafından oluşan bir dönüşüme, bir afin dönüştürmesi denir.

Örneğin, (0,2, 0,0, 0,4, 1,0) rengiyle başlamak istediğinizi varsayın ve aşağıdaki dönüşümleri uygulayın:

  1. Çift kırmızı bileşen

  2. Kırmızı, yeşil ve mavi bileşenlere 0,2 ekleyin

Aşağıdaki matris çarpma, dönüştürme çiftini listelenen sırayla gerçekleştirir.

Screenshot of a transformation multiplication matrix.

Bir renk matrisinin öğeleri, satır ve sonra sütununa göre dizinlenir (sıfır tabanlı). Örneğin, beşinci satır ve üçüncü matris sütunundaki giriş, d [4] [2] ile belirtilir.

5 × 5 kimlik matrisi (aşağıdaki çizimde gösterildiği gibi) köşegen ve diğer her yerde öğeleri üzerinde 1 USD içerir. Bir renk vektörünü kimlik matrisi ile çarpmanız halinde renk vektörü değişmez. Bir renk dönüşümünün matrisini oluşturmanın kolay bir yolu, kimlik matrisine başlamak ve istenen dönüşümü üreten küçük bir değişiklik yapmak.

Screenshot of a 5x5 identity matrix for color transformation.

Matrislerin ve dönüşümlerin daha ayrıntılı bir açıklaması için bkz. koordinat sistemleri ve dönüştürmeleri.

Örnek

Aşağıdaki örnek, bir renk (0,2, 0,0, 0,4, 1,0) olan bir görüntü alır ve önceki paragraflarda tanımlanan dönüştürmeyi uygular.

Aşağıdaki çizimde, sol taraftaki orijinal görüntü ve sağ taraftaki dönüştürülen görüntü gösterilmektedir.

A purple square on the left and a fuchsia square on the right.

Aşağıdaki örnekteki kod, recoloring işlemini gerçekleştirmek için aşağıdaki adımları kullanır:

  1. Bir ColorMatrix nesne başlatın.

  2. Bir ImageAttributes nesne oluşturun ve nesneyi ColorMatrixSetColorMatrix nesne yöntemine geçirin ImageAttributes .

  3. ImageAttributesNesneyi DrawImage bir nesne yöntemine geçirin 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)

Kod Derleniyor

yukarıdaki örnek, Windows Forms kullanımı için tasarlanmıştır ve PaintEventArgse olay işleyicisinin bir parametresi olan gerektirir Paint .

Ayrıca bkz.