Zuerst wird beschrieben, was ein Pixelbild ist. Dann wird gezeigt, wie Sie in Gambas die Farben aller Bildpunkte eines Pixelbildes auslesen. Abschließend werden Ihnen Algorithmen vorgestellt, bei denen Image-Matrizen verändert werden, um bestimmte Bild-Effekte wie zum Beispiel einen Negativ-Effekt oder eine Spiegelung zu erzielen.
Abbildung 23.2.4.10.1.1: Negativ-Effekt
Um Farbwerte eines Pixels in einem Image zu erhalten oder zu setzen, können Sie die Klasse Image als zweidimensionales Array auffassen: Image[x,y] würde sich auf das Pixel an der Position P(x, y) innerhalb des Bildes beziehen.
So können Sie die Farbe eines bestimmten Pixels an der Position P(x,y) auslesen:
Dim hImage As Image Dim iColor As Integer iColor = hImage [ X As Integer, Y As Integer ]
und so setzen Sie die Farbe eines bestimmten Pixels an der Position P(x,y):
Dim hImage As Image Dim iColor As Integer hImage [ X As Integer, Y As Integer ] = iColor
Mit dem folgenden Quelltext können Sie aus einem Pixelbild die Farben aller Bildpunkte P(x,y) auslesen und in einer Gambas-Konsole anzeigen:
[1] Public Sub ShowImageMatrix(hImage As Image) [2] [3] Dim iX, iY As Integer [4] Dim sColor As String [5] [6] '-- Iteration line by line [7] For iY = 0 To hImage.H - 1 [8] '-- Iteration column by column [9] For iX = 0 To hImage.W - 1 [10] Select Case hImage[iX, iY] [11] Case 16711680 [12] sColor = "R" [13] Case 65280 [14] sColor = "G" [15] Case 255 [16] sColor = "B" [17] Case Else [18] sColor = "Y" [19] End Select [20] [21] Print "(" & Str(iY + 1) & "|" & Str(iX + 1) & "): " & sColor [22] '-- Print "(" & Str(iY + 1) & "|" & Str(iX + 1) & ") -> " & Str(hImage[iX, iY]) [23] Next [24] Next [25] [26] End [27] [28] Public Sub btnShowImageMatrix_Click() [29] [30] ShowImageMatrix(Image.Load("images/8x8.png")) [31] [32] End
Abbildung 23.2.4.10.1.2: 8×8-Pixel-Bild
Image-Matrix mit den Koordinaten und Farben:
(1|1):R (1|2):R (1|3):R (1|4):R (1|5):R (1|6):R (1|7):R (1|8):R (2|1):R (2|2):G (2|3):G (2|4):G (2|5):G (2|6):G (2|7):G (2|8):R (3|1):R (3|2):G (3|3):B (3|4):B (3|5):B (3|6):B (3|7):G (3|8):R (4|1):R (4|2):G (4|3):B (4|4):Y (4|5):Y (4|6):B (4|7):G (4|8):R (5|1):R (5|2):G (5|3):B (5|4):Y (5|5):Y (5|6):B (5|7):G (5|8):R (6|1):R (6|2):G (6|3):B (6|4):B (6|5):B (6|6):B (6|7):G (6|8):R (7|1):R (7|2):G (7|3):G (7|4):G (7|5):G (7|6):G (7|7):G (7|8):R (8|1):R (8|2):R (8|3):R (8|4):R (8|5):R (8|6):R (8|7):R (8|8):R
Sie können die Zeilen 9 bis 19 sowie die Zeile 21 – die so nur für das o.a. Bild 8×8.png gelten – für andere Bilder als Kommentar setzen und durch die Zeile 22 ersetzen.
Im folgenden Abschnitt wird Ihnen anhand von zwei Beispielen gezeigt, wie Sie die Farben eines Original-Pixelbildes an den Positionen P(x,y) auslesen und die Image-Matrix eines neuen Bildes schreiben. Typisch dafür sind diese beiden Konzepte:
Die folgenden Beispiele sind zum Teil mit nativen Methoden der Image-Klasse schneller und einfacher realisierbar. Sie wurden trotzdem umgesetzt, um die Verwendbarkeit der Pixel-Matrix auf einfache Weise zu veranschaulichen.
Im Beispiel 1 wird das Konzept_1 umgesetzt, um einen Sepia-Effekt zu erzeugen.
Abbildung 23.2.4.10.1.3: Sepia-Effekt
Folgender Algorithmus beschreibt die notwendige Bild-Manipulation:
Viele Algorithmen basieren auf Artikeln auf der sehr gut konzipierten und interessanten Webseite https://www.geeksforgeeks.org/image-processing-in-java-colored-image-to-sepia-image-conversion/.
Quelltext:
Public Function Image2Sepia(hImage As Image) As Image Dim iX, iY As Integer Dim iOldRed, iOldGreen, iOldBlue, iNewRed, iNewGreen, iNewBlue As Integer Dim tmpImage As Image tmpImage = New Image(hImage.W, hImage.H, Color.White) '-- Iteration line by line For iY = 0 To hImage.H - 1 '-- Iteration column by column For iX = 0 To hImage.W - 1 iOldRed = Color[hImage[iX, iY]].Red iOldGreen = Color[hImage[iX, iY]].Green iOldBlue = Color[hImage[iX, iY]].Blue iNewRed = Int(0.393 * iOldRed + 0.769 * iOldGreen + 0.189 * iOldBlue) If iNewRed > 255 Then iNewRed = 255 iNewGreen = Int(0.349 * iOldRed + 0.686 * iOldGreen + 0.168 * iOldBlue) If iNewGreen > 255 Then iNewGreen = 255 iNewBlue = Int(0.272 * iOldRed + 0.534 * iOldGreen + 0.131 * iOldBlue) If iNewBlue > 255 Then iNewBlue = 255 tmpImage[iX, iY] = Color.RGB(iNewRed, iNewGreen, iNewBlue) Next Next Return tmpImage End Public Sub btnDoSepia_Click() lblChanged.Text = "C H A N G E D - S E P I A" imgChanged = Image2Sepia(imgOriginal) pboxChanged.Picture = imgChanged.Picture End
Um zum Beispiel ein Bild horizontal zu spiegeln, müssen Sie das Konzept_2 mit einem speziellen Algorithmus kombinieren:
Abbildung 23.2.4.10.1.4: Horizontale Spiegelung
Dieser Quelltext wird verwendet:
Public Function ImageMirroring(hImage As Image, sMode As String) As Image Dim iX, iY As Integer Dim tmpImage As Image '-- Spiegelungsrichtung entspricht einer horizontalen Linie tmpImage = New Image(hImage.W, hImage.H) '-- Iteration line by line For iY = 0 To hImage.H - 1 '-- Iteration column by column For iX = 0 To hImage.W - 1 If Upper(sMode) = "H" Then tmpImage[iX, iY] = hImage[hImage.W - iX - 1, iY] Else tmpImage[iX, iY] = hImage[iX, hImage.H - iY - 1] Endif Next Next Return tmpImage End Public Sub btnDoMirrorV_Click() lblChanged.Text = "C H A N G E D - M I R R OR (V)" imgChanged = ImageMirroring(imgOriginal, "V") pboxChanged.Picture = imgChanged.Picture End
Im Download-Bereich finden Sie ein Quelltext-Archiv für die Beispiele 1 bis 7 für eigene Erkundungen.
Beispiel 3
Abbildung 23.2.4.10.1.5: Graustufenbild
Beispiel 4
Abbildung 23.2.4.10.1.6: Negativ-Effekt
Beispiel 5
Abbildung 23.2.4.10.1.7: Vertikale Spiegelung
Beispiel 6
Abbildung 23.2.4.10.1.8: Mono-Color-Effekt
Beispiel 7
Abbildung 23.2.4.10.1.9: Bild mit kreisförmigem Ausschnitt
Das Beispiel 7 basiert auf einem Quelltext des Gambas-Buch-Autors Claus Dietrich.
Quelltext:
Public Function Image2Circle(hImage As Image) As Image Dim iX, iY As Integer Dim tmpImage As Image Dim fAngle As Float Dim fRadius As Float Dim fD As Float Dim fYY As Float tmpImage = New Image(hImage.W, hImage.H) tmpImage = hImage fRadius = tmpImage.H / 2 For iX = 0 To tmpImage.W / 2 - fRadius For iY = 0 To tmpImage.H - 1 '-- Make sure that the alpha channel of the colour is used so that '-- the colour becomes transparent. So &HFFFFFFFF instead of &HFFFFFF! tmpImage[iX, iY] = &HFFFFFFFF tmpImage[tmpImage.W / 2 + fRadius + iX, iY] = &HFFFFFFFF Next Next For iX = (tmpImage.W - 1) / 2 To (tmpImage.W - 1) / 2 - fRadius Step -1 fD = ((tmpImage.W - 1) / 2 - iX) / fRadius fAngle = ACos(fD) fYY = 1 - Sin(fAngle) For iY = 0 To fYY * fRadius tmpImage[iX, iY] = &HFFFFFFFF tmpImage[iX, tmpImage.H - iY] = &HFFFFFFFF Next Next For iX = (tmpImage.W - 1) / 2 To (tmpImage.W - 1) / 2 + fRadius fD = ((tmpImage.W - 1) / 2 - iX) / fRadius fAngle = ACos(fD) fYY = 1 - Sin(fAngle) For iY = 0 To fYY * fRadius tmpImage[iX, iY] = &HFFFFFFFF tmpImage[iX, tmpImage.H - iY] = &HFFFFFFFF Next Next Return tmpImage End Public Sub btnDoCircle_Click() lblChanged.Text = "C H A N G E D - T O C L I P C I R C L E" imgChanged = Image2Circle(imgOriginal.Copy()) pboxChanged.Picture = imgChanged.Picture End