Firstly, we describe what a pixel image is. Then it is shown how to read out the colours of all pixels of a pixel image in Gambas. Finally, algorithms are presented in which image matrices are changed in order to achieve certain image effects such as a negative effect or a reflection.
Figure 23.2.4.10.1.1: Negative effect
To get or set the colour values of a pixel in an image, you can use the Image class as a two-dimensional array: Image[x,y] would refer to the pixel at position P(x, y) within the image.
This allows you to read out the colour of a specific pixel at position P(x,y):
Dim hImage As Image Dim iColor As Integer iColor = hImage [ X As Integer, Y As Integer ]
and to set the colour of a specific pixel at the position P(x,y):
Dim hImage As Image Dim iColor As Integer hImage [ X As Integer, Y As Integer ] = iColor
With the following source code, you can read the colours of all pixels P(x,y) from a pixel image and display them in a Gambas console:
[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
Figure 23.2.4.10.1.2: 8×8 pixel image
Image matrix with coordinates and colours:
(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
You can set lines 9 to 19 and line 21 - which only apply to the 8×8.png image above - as comments for other images and replace them with line 22.
The following section uses two examples to show you how to read the colours of an original pixel image at the positions P(x,y) and write the image matrix of a new image. These two concepts are typical:
Some of the following examples can be realised more quickly and easily using native methods of the Image class. Nevertheless, they have been implemented in order to illustrate the usability of the pixel matrix in a simple way.
In example 1, concept_1 is implemented to create a sepia effect.
Figure 23.2.4.10.1.3: Sepia effect
The following algorithm describes the necessary image manipulation:
Many algorithms are based on articles on the very well-designed and interesting website https://www.geeksforgeeks.org/image-processing-in-java-colored-image-to-sepia-image-conversion/.
Source code:
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
For example, to flip an image horizontally, you need to combine concept_2 with a special algorithm:
Figure 23.2.4.10.1.4: Horizontal mirroring
This source code is used:
Public Function ImageMirroring(hImage As Image, sMode As String) As Image Dim iX, iY As Integer Dim tmpImage As Image '-- Mirroring direction corresponds to a horizontal line 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
In the download area you will find a source code archive for examples 1 to 7 for your own explorations.
Example 3
Figure 23.2.4.10.1.5: Greyscale image
Example 4
Figure 23.2.4.10.1.6: Negative effect
Example 5
Figure 23.2.4.10.1.7: Vertical reflection
Example 6
Figure 23.2.4.10.1.8: Mono colour effect
Example 7
Figure 23.2.4.10.1.9: Image with circular section
Example 7 is based on a source text by the Gambas book author Claus Dietrich.
Source code:
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