Porady: stosowanie macierzy kolorów do transformacji pojedynczego koloru
GDI+ udostępnia Image klasy i Bitmap do przechowywania obrazów i manipulowania nimi. Image obiekty i Bitmap przechowują kolor każdego piksela jako 32-bitową liczbę: 8 bitów każdy dla czerwonego, zielonego, niebieskiego i alfa. Każdy z czterech składników jest liczbą z zakresu od 0 do 255, a 0 nie reprezentuje intensywności i 255 reprezentujących pełną intensywność. Składnik alfa określa przezroczystość koloru: 0 jest w pełni przezroczysty, a 255 jest w pełni nieprzezroczyste.
Wektor kolorów jest krotką 4-krotkową formularza (czerwona, zielona, niebieska, alfa). Na przykład wektor kolorów (0, 255, 0, 255) reprezentuje nieprzezroczystym kolorem, który nie ma czerwonego lub niebieskiego, ale ma zielony z pełną intensywnością.
Inna konwencja reprezentowania kolorów używa liczby 1 dla pełnej intensywności. Przy użyciu tej konwencji kolor opisany w poprzednim akapicie będzie reprezentowany przez wektor (0, 1, 0, 1, 1). GDI+ używa konwencji 1 jako pełnej intensywności podczas wykonywania przekształceń kolorów.
Przekształcenia liniowe (rotacja, skalowanie i podobne) można stosować do wektorów kolorów, mnożąc wektory kolorów przez macierz 4×4. Nie można jednak użyć macierzy 4×4 do wykonania tłumaczenia (nieliniowego). Jeśli do każdego z wektorów kolorów zostanie dodana fikcyjna piąta współrzędna (na przykład liczba 1), można użyć macierzy 5×5, aby zastosować dowolną kombinację przekształceń liniowych i tłumaczeń. Transformacja składająca się z transformacji liniowej, po której następuje tłumaczenie, jest nazywana transformacją affiną.
Załóżmy na przykład, że chcesz zacząć od koloru (0.2, 0.0, 0.4, 1.0) i zastosować następujące przekształcenia:
Podwaja czerwony składnik
Dodaj 0.2 do czerwonych, zielonych i niebieskich składników
Następujące mnożenie macierzy wykona parę przekształceń w podanej kolejności.
Elementy macierzy kolorów są indeksowane (oparte na zerze) według wiersza, a następnie kolumny. Na przykład wpis w piątym wierszu i trzeciej kolumnie macierzy M
jest oznaczany przez M[4][2]
.
Macierz tożsamości 5×5 (pokazana na poniższej ilustracji) ma 1s na przekątnej i 0s wszędzie indziej. Jeśli pomnożysz wektor kolorów przez macierz tożsamości, wektor kolorów nie zmieni się. Wygodnym sposobem utworzenia macierzy transformacji kolorów jest rozpoczęcie od macierzy tożsamości i wprowadzenie małej zmiany, która generuje żądaną transformację.
Aby uzyskać bardziej szczegółową dyskusję na temat macierzy i przekształceń, zobacz Koordynowanie systemów i przekształceń.
Przykład
Poniższy przykład przedstawia obraz, który jest jednym kolorem (0.2, 0.0, 0.4, 1.0) i stosuje transformację opisaną w poprzednich akapitach.
Poniższa ilustracja przedstawia oryginalny obraz po lewej stronie i przekształcony obraz po prawej stronie.
Kod w poniższym przykładzie używa następujących kroków w celu ponownego kolorowania:
Inicjowanie ColorMatrix obiektu.
ImageAttributes Utwórz obiekt i przekaż ColorMatrix obiekt do SetColorMatrix metody ImageAttributes obiektu.
ImageAttributes Przekaż obiekt do DrawImage metody Graphics obiektu.
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)
Kompilowanie kodu
Powyższy przykład jest przeznaczony do użycia z formularzami Windows Forms i wymaga PaintEventArgse
parametru , który jest parametrem Paint programu obsługi zdarzeń.
Zobacz też
.NET Desktop feedback
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla