How to get alpha value from ReadPixel

BlitzMax Forums/BlitzMax Beginners Area/How to get alpha value from ReadPixel

Rooster(Posted 2016) [#1]
My understanding is that ReadPixel gives you a pixels rgb and alpha values. So how do I get the the alpha on its own, or any other value for that matter?


JBR(Posted 2016) [#2]
pix% = readpixel()

alpha = (pix% & $ff000000) shr 24

red = (pix% & $00ff0000) shr 16

green = (pix% & $0000ff00) shr 8

blue = (pix% & $000000ff)


All between 0 to 255


dw817(Posted 2016) [#3]
You can confirm that JBR's function is correct and accurate by the following code, Rooster:
pix=$FFEE6040

a=(pix&$ff000000)Shr 24
r=(pix&$ff0000)Shr 16
g=(pix&$ff00)Shr 8
b=pix&$ff
Print"Alpha="+Hex$(a)
Print"Red  ="+Hex$(r)
Print"Green="+Hex$(g)
Print"Blue ="+Hex$(b)


If you want tighter code with no parenthesis or trailing zeros but still get the same results, you can use my smaller model of:
pix=$FFEE6040
a=pix Shr 24&$ff
r=pix Shr 16&$ff
g=pix Shr 8&$ff
b=pix&$ff
Print"Alpha="+Hex$(a)
Print"Red  ="+Hex$(r)
Print"Green="+Hex$(g)
Print"Blue ="+Hex$(b)
Hope This Helps !


Rooster(Posted 2016) [#4]
Thanks! :)


Kryzon(Posted 2016) [#5]
ReadPixel returns an Int that has the packed channel values for the pixel in the coordinates of the pixmap that you supplied to the function.
The amount of channels and the order that they're packed in depends on the format of the pixmap that you're ReadPixel-ing from.

The code above assumes it's a 32 bit A,R,G and B pixel, like 0xAARRGGBB.
BlitzMax does not have that pixmap format. The formats with alpha put it at the end.

http://www.blitzbasic.com/bmdocs/command.php?name=CreatePixmap&ref=2d_cat


TomToad(Posted 2016) [#6]
Readpixel will reformat the color data into AARRGGBB regardless of the original format. No need to worry about byte order. If you read directly from the pixel array with Pixmap.pixels[], then the Pixmap format becomes important.


dw817(Posted 2016) [#7]
Kryzon, Tom, while I have you guys on the horn, is there any way to get a 256-color screen with custom palette using:
PF_I8	8 bit intensity
or some other method of image creation ?

If a single byte can be used to represent a single pixel with a custom palette, I would think it would run 3x faster to read and write pixels and you'd have the added ability of being able to animate palettes as well.


TomToad(Posted 2016) [#8]
Kryzon, Tom, while I have you guys on the horn, is there any way to get a 256-color screen with custom palette using:
PF_I8 8 bit intensity
or some other method of image creation ?

Simple answer, No.

More complex answer, Yes, but some explanation.

Most of this stuff you probably already know, but might get confused about the details. BlitzMax itself is actually incapable of doing any graphics at all. It can't do files, or sound, or lists, or any of those neat commands we rely on. BltzMax consists of a few basic commands. Flow control, primitives and types, some simple expression and math evaluation. The rest of the functionality that we rely on come in small files known as modules. Because of these modules, we could potentially have BlitzMax perform just about anything any other programming languages can.

Now it is understood by most here that when you ask if BlitzMax is capable of some function, you are actually referring to the core BlitzMax and all the modules that come packaged with it. The graphics module that ships with BM is called Max2D. It is a very powerful 2D engine, but does have its limitations.

Max2D uses a method known as 2D-in-3D. The TImages you create are actually rectangles that exists in 3D space, but they are always facing the camera and projected onto a flat plane so they appear 2D. What this means is that you now have all the 3D acceleration functions available to you, super fast rotation, scaling, alpha, and the ability to render tons of images in a single frame. Unfortunately, it also means that simple 2D functions are now crippled. Making single pixel changes, and drawing bitmaps (pixmap in BM lingo) are much slower.

The good news is that since Max2D is a module, it can be modified or even replaced. If superfast rotation and scaling are not important to you, but pixel manipulation is, you can create a GDI module or a DirectDraw module which would give you better access to the 2D functions.

Also need to mention one thing about 8 bit palette images. Most modern graphics card are incapable of 8 bit graphics. There are actually very few left capable of 16 bit. Any programs that request these modes will run in 24 or 32 bit mode and the functions will be emulated by the drivers. I have old software that actually runs slower on modern hardware than they do on 10 year old systems just for that reason.


Kryzon(Posted 2016) [#9]
Readpixel will reformat the color data into AARRGGBB regardless of the original format.

Thank you, that's interesting.

About paletting, the modern way to do it would be to have a greyscale image and use a 1D texture of 256 x 1 size, with each texel being a colour in the palette.
Then use a simple shader that outputs a pixel colour by sampling the palette texture:
[...]
gl_FragColor = texture1D( myPalette, texture2D( myImage, texCoords ).r );
You're using the "r" (red) channel of the sampled greyscale image as a texture coordinate in the palette texture. You can do this because colours in GLSL are handled in float format, in range [0.0, 1.0]. This sort of value can be used as a texture coordinate. It should work best if the texture is set to "nearest neighbour" sampling mode.
The GPU would eat this for breakfast.

It's possible to write a utility in BMax that takes an image, converts it to greyscale and generates the 1D texture palette that goes with it. Otherwise it'd be too tiresome to do it by hand.


TomToad(Posted 2016) [#10]
To convert a pixmap to greyscale, ConvertPixmap(Pixmap,PF_I8)
You can also convert to shades of red, green, or blue with PF_RED, PF_GREEN, and PF_BLUE. You can then turn the resulting pixmap into a TImage with LoadImage(Pixmap)

As for doing palettes with shaders, I was thinking of using a uniform vec3 array. Supposedly, uniforms will remain persistent as long as the shader is running. Thinking the idea of a 256x1 texture would be better as it will remain persistent even across different shaders.


Kryzon(Posted 2016) [#11]
The greyscale version has to be generated with the reasoning that the red channel should represent the U texture coordinate in the 1D texture, so the final processed image may look weird visually while the data is correct. I don't think it'd work with the standard conversion function.

You first build a table of the 256 colours present in the image (and make adaptations in case the image has more than that amount), then go through each pixel in the image and assign the red channel a byte value that represents the index in that 256-item table.
When the image is sampled in shader, the red channel will be numerically the same as the U coordinate in the palette texture that points to the appropriate colour.

EDIT: There's some more info here http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter24.html


dw817(Posted 2016) [#12]
Morning guys, do you have any examples of working with an 8-bit screen and 256-color palette ?

Failing that from what I'm reading (and not understanding for the most part), it sounds complex.

However, it should be possible given that QBasic, a superior inferior language could do it so easily with a single command, "SCREEN 13"

https://en.wikipedia.org/wiki/Mode_13h

BTW, TomToad. Your method of converting an image to B&W is remarkably fast and easy. Surprising since I've seen code that converts it by reading and writing each pixel.
Strict
Graphics 640,480
Local pic:TPixmap=LoadPixmap("froggy.jpg")
DrawPixmap pic,0,0
Flip
WaitKey
pic=ConvertPixmap(pic,pf_i8)
DrawPixmap pic,0,0
Flip
WaitKey



TomToad(Posted 2016) [#13]
a superior inferior language

Does that mean that out of all the inferior languages out there, this is the least inferior? Or does it mean that as for being inferior, this rules them all?


dw817(Posted 2016) [#14]
Now Tom, you notice I used both words of superior inferior. This means QBasic for it's time it was a superior programming language, today it is inferior. :)