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
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)
global origHeight, origWidth, image1
repeat with tPixel = 0 to (origHeight * origWidth ) - 1
put tPixel * 4 into pixelStart
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
set the imageData of image "newImage" to image1
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...)
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 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 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
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
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
|
 Updating...
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
cyril.pruszko@pgcps.org, Dec 19, 2016, 6:32 PM
|