Home‎ > ‎Digital Magic‎ > ‎

DI_Pixels

Digital Images - Pixels

Pixels

In LiveCode, each pixel of an image is represented as 4 bytes which you access as single-byte characters. The range of values for each byte is 0-255. They are stored as characters and must be converted. (In the early days of computers, a 0 meant it was the end of a file. In order to be able to use zeros, we just convert the numbers into a character and back

You must convert the character value into a numeric value before using it. We use the "charToNum" function and to convert it back, we use the "numToChar" function

Also each pixel is store as 4 bytes. They are, in order, "Alpha","Red",Green","Blue". The first byte is the Alpha value which is used differently by different images (if, png, jpg, etc). We are going to ignore it since we do not need it. The other 3 will be converted into their number for each color (RGB).


Looking at Every Pixel

    We are going to use a loop to go through every pixel in our image. Normally, we would go through each pixel with a repeat. Say we had a 2 MP or 2 megapixel image  (which is 2 million pixels)

repeat with tPixel = 1 to 2000000                                           // this gets each pixel, one by one.
     put tPixel * 4 into pixelStart                                                                          // each pixel is 4 bytes long
     ...
end repeat

The reason is that for each pixel, we have to load the 4 bytes for that pixel (Alpha, Red, Green, Blue ). So we have to start at the beginning at 0  and load bytes 1-4 for the first one and every pixel after that

We start at 0 and go to the # -1.  
        So if we have 10 pixels, we go from 0 to 9.    (10 -1)
            If we have 500,000 pixels, we go from 0 to 499,999     (500,000 -1)
    If we have 2 million pixels ( 2,000,000), we go from 0 to 1,999,999.   (2,000,000-1)

repeat with tPixel = 0 to 199999999                                           // this gets each pixel, one by one.
     put tPixel * 4 into pixelStart                                                                          // each pixel is 4 bytes long
     ...
end repeat


Since we have different sized images, we should just calculate the # pixels from the picture size and write it like this

repeat with tPixel = 0 to (origHeight  * origWidth ) - 1                                        // this gets each pixel, one by one.
     ...
end repeat



Our code is now this:

repeat with tPixel = 0 to (origHeight  * origWidth ) - 1                                        // this gets each pixel, one by one.
      put tPixel * 4 into pixelStart                                                                          // each pixel is 4 bytes long
                 ...
           end repeat

Getting Each Color

Each color is a number from 0 to 255. But saving zeros is a problem for computers. Zero is a special marker for the end of a file/message/etc. Many programs also look for the length in a field and if it finds a zero, it thinks that the rest is empty.

So if a pixel has a zero in it, the computer will stop there, figuring that it is at the end. So we save the numbers as characters.  
 This means that we have to convert the number to a char to store it and from a char to a number to unpack it.

We use the charToNum and numToChar built-in functions in LiveCode

pixelStart contains the 4 characters (bytes) and we next have to unpack them (unload each character separately and cover it to a number (0-255)

      put  charToNum (char (pixelStart + 1) of image1) into tAlpha                     // byte #1 is the Alpha
      put  charToNum (char (pixelStart + 2) of image1) into tRed                       // byte #2 is the Red
      put charToNum (char (pixelStart + 3) of image1) into tGreen                     // byte #3 is the Green
      put charToNum (char (pixelStart + 4) of image1) into tBlue                       // byte #4 is the Blue 
    

What everything looks like:

    The image below is of a arrowhead inside a circle
        the window "saveImage" shows the numbers saved as characters
        the window "thecolors" shows the actual numbers (RGB)

                         

    notes:
        1. notice that the black pixels are not all 0,0,0.  They can be 69,69,69 or 12,12,12 or any other low numbers. Our eyes are not that good to notice the differences
        2. notice also that the whites are not always 255,255,255. They are numbers like 254,254,254 or 203,203,203 or 114,114,114.
        3. Any pixel that has the same number for all 3 colors (RGB) will give a black or gray pixel.
        4. I put the actual RGB numbers by adding the lines of code (in red)
on mouseUp
   global origHeight, origWidth, image1
   
   lock screen
   upsize
   global thecolors
   put empty into thecolors
   
   repeat with tPixel = 0 to (origHeight  * origWidth ) - 1
      put tPixel * 4 into pixelStart
      
      // get the color values
      put  charToNum (char (pixelStart + 1) of image1) into tAlpha
      put  charToNum (char (pixelStart + 2) of image1) into tRed
      put charToNum (char (pixelStart + 3) of image1) into tGreen
      put charToNum (char (pixelStart + 4) of image1) into tBlue
      
      put tRed & "," & tGreen & "," & tBlue & return after thecolors

      // Change the color values
      put numToChar (255) into char (pixelStart + 2) of image1  // Red
      //put numToChar (0) into char (pixelStart + 3) of image1      // Green
      //put numToChar (0) into char (pixelStart + 4) of image1     // Blue
      
   end repeat
   set the imageData of image "newImage" to image1
   
   downSize
   unlock screen


Here is the complete code that goes through every pixel and gets each number:

repeat with tPixel = 0 to (origHeight  * origWidth ) - 1                                        // this gets each pixel, one by one.
      put tPixel * 4 into pixelStart                                                                          // each pixel is 4 bytes long
      put  charToNum (char (pixelStart + 1) of image1) into tAlpha                     // byte #1 is the Alpha
      put  charToNum (char (pixelStart + 2) of image1) into tRed                       // byte #2 is the Red
      put charToNum (char (pixelStart + 3) of image1) into tGreen                     // byte #3 is the Green
      put charToNum (char (pixelStart + 4) of image1) into tBlue                       // byte #4 is the Blue 
       (now to do something with the pixels...)
end repeat

Changing Pixels

Suppose we wanted to change red pixels to Green ones. We look to see if the pixel has red in it. 
If it does, we change it to 0 (no red) and change the Green to 255 (max Green)


repeat with tPixel = 0 to (origHeight  * origWidth ) - 1                                        // this gets each pixel, one by one.
      put tPixel * 4 into pixelStart                                                                          // each pixel is 4 bytes long
      put  charToNum (char (pixelStart + 1) of image1) into tAlpha                     // byte #1 is the Alpha
      put  charToNum (char (pixelStart + 2) of image1) into tRed                       // byte #2 is the Red
      put charToNum (char (pixelStart + 3) of image1) into tGreen                     // byte #3 is the Green
      put charToNum (char (pixelStart + 4) of image1) into tBlue                       // byte #4 is the Blue 
      if tRed >200 then
         put numToChar (0) into char (pixelStart + 2) of image1  // Red
         put numToChar (255) into char (pixelStart + 3) of image1      // Green
         put numToChar (0) into char (pixelStart + 4) of image1     // Blue
      end if
end repeat

Here is the code that goes through every pixel and gets each number:

repeat with tPixel = 0 to (origHeight  * origWidth ) - 1                                        // this gets each pixel, one by one.
      put tPixel * 4 into pixelStart                                                                          // each pixel is 4 bytes long
      put  charToNum (char (pixelStart + 1) of image1) into tAlpha                     // byte #1 is the Alpha
      put  charToNum (char (pixelStart + 2) of image1) into tRed                       // byte #2 is the Red
      put charToNum (char (pixelStart + 3) of image1) into tGreen                     // byte #3 is the Green
      put charToNum (char (pixelStart + 4) of image1) into tBlue                       // byte #4 is the Blue 
      if tRed >200 then
         put numToChar (0) into char (pixelStart + 2) of image1  // Red
         put numToChar (255) into char (pixelStart + 3) of image1      // Green
         put numToChar (0) into char (pixelStart + 4) of image1     // Blue
      end if
end repeat



Now Your Turn

    Download the file "Digital_Image_B&W_1" at the bottom of this page. Start up LiveCode 6 (or up) and open the file.

    Click on the "Change Color" button and you will see the above code execute.

                         


    Edit the code on the button to:

        1. Change the color of the "X" to Blue
        2. Change the color of the "X" to Yellow (Red + Green)
  

The Challenge

    Try the next file - "Digital_Image_B&W_2" and run it in LiveCode
    Load the file "x.png"

                         


    Edit the code on the button to:
    
        3. Change the White X to a Red X
        4. Change the Black background to Green (hint: remember black is no colors (all zeros)


Try loading some other photos and experiment with them


ą
cyril.pruszko@pgcps.org,
Dec 20, 2016, 4:58 AM
ċ
Digital_Image_B&W_1.livecode
(1867k)
cyril.pruszko@pgcps.org,
Dec 20, 2016, 4:57 AM
ċ
Digital_Image_B&W_2.livecode
(1866k)
cyril.pruszko@pgcps.org,
Dec 20, 2016, 4:57 AM
ą
cyril.pruszko@pgcps.org,
Dec 20, 2016, 4:58 AM
ą
x.png
(0k)
cyril.pruszko@pgcps.org,
Dec 19, 2016, 6:32 PM
Comments