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

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

Renk vektörleri formun 4 tanımlama grubudur (kırmızı, yeşil, mavi, alfa). Örneğin, renk vektöru (0, 255, 0, 255), kırmızı veya mavi olmayan, ancak tam yoğunlukta yeşil olan opak bir rengi temsil eder.

Renkleri temsil etmek için kullanılan başka bir kural da tam yoğunluk için 1 sayısını kullanır. Bu kural kullanıldığında, önceki paragrafta açıklanan renk vektörle (0, 1, 0, 1) temsil edilir. GDI+, renk dönüşümleri gerçekleştirirken tam yoğunluk olarak 1 kuralını kullanır.

Renk vektörlerini 4×4 matrisle çarparak renk vektörlerine doğrusal dönüştürmeler (döndürme, ölçeklendirme ve benzeri) uygulayabilirsiniz. Ancak, çeviri (doğrusal olmayan) gerçekleştirmek için 4×4 matrisi kullanamazsınız. Renk vektörlerinin her birine sahte bir beşinci koordinat (örneğin, 1 sayısı) eklerseniz, doğrusal dönüştürmelerin ve çevirilerin herhangi bir bileşimini uygulamak için 5×5 matrisi kullanabilirsiniz. Doğrusal bir dönüşümden ve ardından çeviriden oluşan bir dönüşüm, benze dönüştürme olarak adlandırılır.

Örneğin, renkle (0.2, 0.0, 0.4, 1.0) başlamak istediğinizi ve aşağıdaki dönüştürmeleri uygulamak istediğinizi varsayalım:

  1. Kırmızı bileşeni iki katına çıkarma

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

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

Screenshot of a transformation multiplication matrix.

Renk matrisinin öğeleri satıra ve sonra sütuna göre dizinlenir (sıfır tabanlı). Örneğin, matrisin M beşinci satırındaki ve üçüncü sütunundaki girdi tarafından M[4][2]belirtilir.

5×5 kimlik matrisinin (aşağıdaki çizimde gösterilmiştir) çapraz üzerinde 1'ler, diğer her yerde 0'lar bulunur. Renk vektörlerini kimlik matrisi ile çarpıyorsanız, renk vektöru değişmez. Renk dönüştürme matrisini oluşturmanın kullanışlı bir yolu, kimlik matrisiyle başlamak ve istenen dönüşümü üreten küçük bir değişiklik yapmaktır.

Screenshot of a 5x5 identity matrix for color transformation.

Matrisler ve dönüşümler hakkında daha ayrıntılı bir tartışma için bkz . Koordinat Sistemleri ve Dönüşümler.

Örnek

Aşağıdaki örnek, tümü tek renkli (0,2, 0,0, 0,4, 1,0) bir görüntü alır ve önceki paragraflarda açıklanan dönüşümü uygular.

Aşağıdaki çizimde, soldaki özgün görüntü ve sağda dönüştürülmüş görüntü gösterilmektedir.

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

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

  1. Bir ColorMatrix nesneyi başlatın.

  2. Bir ImageAttributes nesne oluşturun ve nesnesini nesnesinin SetColorMatrix yöntemine ImageAttributes geçirinColorMatrix.

  3. ImageAttributes nesnesini bir Graphics nesnenin DrawImage yöntemine geçirin.

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 ile kullanılmak üzere tasarlanmıştır ve olay işleyicisinin Paint parametresi olan öğesini gerektirir.PaintEventArgse

Ayrıca bkz.