# GAMBAS BOOK 3.19.1

### Site Tools

k23:k23.4:k23.4.2:k23.4.2.10.0:start

## 23.2.4.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.2.4.10.1.1: Negative effect

## 23.2.4.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.2.4.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.2.4.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]
[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.

## 23.2.4.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.2.4.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.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 fD As Float
Dim fYY As Float

tmpImage = New Image(hImage.W, hImage.H)
tmpImage = hImage

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```