01-28-2024, 07:56 PM
Thanks for explaining this. I understand little vs big endian from my assembler dabbling days back in the Z80, 6809e, 6502, and x86 days with each processor handling bit presentation differently. I assumed RGB was presented in bit form the same way as the QB64PE commands are set up. I don't know why this didn't cross my mind though when I was getting some strange results in final images. Age I guess.
Your classroom exercise would have been great to use. I left teaching back in 2018 unfortunately.
I incorporated your suggestion into the following subroutine that converts an image to gray scale. Works well.
Your classroom exercise would have been great to use. I left teaching back in 2018 unfortunately.
I incorporated your suggestion into the following subroutine that converts an image to gray scale. Works well.
Code: (Select All)
' _______________________________________________________________________________________________________
'/ \
SUB __GrayScale (i AS LONG) ' __GrayScale |
' ___________________________________________________________________________________________________|___
'/ \
'| Converts an image to gray scale without affecting original alpha values. |
'| Uses ITU-R 601-2 Luma Transformation (L = R * 299/1000 + G * 587/1000 + B * 114/1000) |
'| |
'| i - the image to work with |
'\_______________________________________________________________________________________________________/
DIM m AS _MEM ' memory block holding image data
DIM o AS _OFFSET ' 4 byte pixel location within memory block
DIM t AS _OFFSET ' total number of pixels in image
DIM a AS _UNSIGNED _BYTE ' alpha level of each pixel
DIM r AS _UNSIGNED _BYTE ' red value of each pixel
DIM g AS _UNSIGNED _BYTE ' green value of each pixel
DIM b AS _UNSIGNED _BYTE ' blue value of each pixel
DIM p AS _UNSIGNED LONG ' new grayscale pixel value
$CHECKING:OFF
m = _MEMIMAGE(i) ' set memory block to image data
t = m.SIZE \ 4 ' calculate number of pixels in image
o = m.OFFSET ' start address of memory block
DO ' begin pixel count
_MEMGET m, o + 3, a ' get alpha (0 to 255)
_MEMGET m, o + 2, r ' get red (0 to 255)
_MEMGET m, o + 1, g ' get green (0 to 255)
_MEMGET m, o, b ' get blue (0 to 255)
p = INT(r * .299 + g * .587 + b * .114) ' calculate gray level
p = _RGBA32(p, p, p, a) ' create new pixel
_MEMPUT m, o, p ' update pixel in memory block
o = o + 4 ' next 4 byte pixel location in memory block
t = t - 1 ' decrement pixels remaining
LOOP UNTIL t = 0 ' leave when no pixels remain
_MEMFREE m ' free memory block
$CHECKING:ON
END SUB