Table of Contents
23.4.2.10.1 Image matrix and image manipulations
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.4.2.10.1.1: Negative effect
23.4.2.10.1.1 Pixel image
- A pixel image (pixel graphic, raster graphic) consists of an xy-grid of mostly square pixels.
- The position of an individual pixel in the image is defined by its xy coordinates P(x,y).
- A pixel represents the pixel colour at the position P(x,y).
23.4.2.10.1.2 Reading or setting colours from a pixel image
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
23.4.2.10.1.3 Example image matrix
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.4.2.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.
23.4.2.10.1.4 Image matrix and image manipulation
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:
- Concept_1 Either the colour values of the image matrix of the original are changed and mapped to the same pixels P'(x,y) of a new image.
- Concept_2 The colour values of the image matrix of the original are mapped unchanged to other pixels of a new image.
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.4.2.10.1.3: Sepia effect
The following algorithm describes the necessary image manipulation:
- (S1) Determine the RGB value of an original pixel P(x,y).
- (S2) Calculate the new RGB values for a sepia effect with the following weightings. Use the integer value.
- newRed = Integer( 0.393 * oldRed + 0.769 * oldGreen + 0.189 * oldBlue)
- newGreen = Integer( 0.349 * oldRed + 0.686 * oldGreen + 0.168 * oldBlue)
- newBlue = Integer( 0.272 * oldRed + 0.534 * oldGreen + 0.131 * oldBlue)
- (S3) Set the new RGB value of the pixel P'(x,y) in the new image according to the following condition:
- If newRed > 255 then newRed = 255
- If newGreen > 255, then newGreen = 255
- If newBlue > 255, then newBlue = 255
- (S4) Replace the RGB values of the original pixel P(x,y) with the values calculated in steps S2 and S3 in the new image in P'(x,y).
- (S5) Repeat steps S1 to S4 for each pixel P(x,y) of the original image.
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:
- (S1) In the new image, replace the RGB value at the point P'(x,y) with the RGB value of the original at the point P(image width - x,y).
- (S2) Repeat step S1 for each pixel P(x,y) of the original image.
Figure 23.4.2.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.4.2.10.1.5: Greyscale image
Example 4
Figure 23.4.2.10.1.6: Negative effect
Example 5
Figure 23.4.2.10.1.7: Vertical reflection
Example 6
Figure 23.4.2.10.1.8: Mono colour effect
Example 7
Figure 23.4.2.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








