May 08, 2024, 05:33:18 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Get pixel info in memory Bitmap

Started by ChanTerra, April 23, 2009, 02:45:34 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ChanTerra

Hi,
I am a newbie with Ebasic, excuse me if the answer is obvious (for you)...
Is there some way to make some image treatment with memory image with Ebasic ?
ie
Is it possible to get pixel information about a bitmat loaded with:
bitmap = LoadImage(filename,@IMGSCALABLE )

without showing the image with "ShowImage" ?

perhaps with "ReadPixel(x as INT,y as INT,opt buffer as POINTER)", but why the pointer is optional there ?
What would be the use of this ?

Thanks

Ionic Wind Support Team

ReadPixel is a 2D DirectX command, and only works with 2D screens.  The optional pointer, as stated in the users guide, is either BACKBUFFER, FRONTBUFFER or SPRITEBUFFER.

Because @IMGSCALABLE can read many types of image files there is no easy way to directly get a pixel from the returned handle, although it can be done through COM.  Since you are just starting out I would recommend you use a hidden window, show the image in the hidden window, and then use GetPixel function.

Paul.
Ionic Wind Support Team

ChanTerra

Thanks Paul for the answer.
In fact I have to analyze a B&W picture, stored in disk (A4 format, 200 dpi). In order to find the coordonates of some patterns (little black squares).
So the scalable option is not needed.

Is there some easy and fast solution ?
Is "GETPIXEL "with an hiden window (that would be out of screen if showed) working ?

Thanks


Ionic Wind Support Team

Yes it will work with a hidden window.

If you have experience with the Windows API then search MSDN for GetBitmapBits, which is another way to accomplish what you want. 

Paul.
Ionic Wind Support Team


fasecero

May 01, 2009, 01:09:12 AM #5 Last Edit: May 01, 2009, 02:28:05 AM by fasecero
Read this topic has interested me much the GetBitmapBits function and its complementary SetBitmapBits, I like the idea of being able to use filters in images using mathematical formulas.
This is my attempt to get the colors of a pixel in an image, but without success ... after several days of trying I finally decided to ask.
I think maybe the problem is in the buffer...



GLOBAL SUB ImageFilter(uint hbitmap)
BITMAP bmp
pointer buffer

' get the bitmap info
_GetObject(hbitmap, LEN(bmp), &bmp)

' get the pixels
buffer=_GlobalAlloc(GPTR, bmp.bmWidthBytes*bmp.bmHeight)
_GetBitmapBits(hbitmap, bmp.bmWidthBytes*bmp.bmHeight, buffer)

                ' here i test a pixel and gets wrong values
DEBUGPRINT "red  : "+STR$( (buffer[32]&0x0000FF ) )
DEBUGPRINT "green: "+STR$( ((buffer[32]&0x00FF00)>>8 ) )
DEBUGPRINT "blue : "+STR$( ((buffer[32]&0xFF0000)>>16 ) )

' do something with the pixels
FOR i=0 TO bmp.bmWidthBytes*bmp.bmHeight-1
' nothing yet
NEXT i

' set the bitmap info
_SetBitmapBits(hbitmap, bmp.bmWidthBytes*bmp.bmHeight, buffer)
ENDSUB




sapero

fasecero, this is a simple and unoptimized shadow effect:
Note, never use GlobalAlloc because memory it returns is very slow on reads and writes. Use it only if your forced to use it (clipboard api)
SUB ImageFilter(uint hbitmap)
BITMAP bmp
pointer buffer

' get the bitmap info
_GetObject(hbitmap, LEN(bmp), &bmp)

' get the pixels
int datalen = bmp.bmWidthBytes * bmp.bmHeight
buffer=AllocHeap(datalen)
_GetBitmapBits(hbitmap, datalen, buffer)

' do something with the pixels
pointer pixel = buffer
int pixelcount = bmp.bmWidth * bmp.bmHeight

float fWidth = 1.0/bmp.bmWidth

if (bmp.bmBitsPixel = 32)
settype pixel, RGBQUAD
int x = 0

FOR i=1 TO pixelcount
float bright = (bmp.bmWidth-x) * fWidth

*pixel.rgbBlue  *= bright
*pixel.rgbGreen *= bright
*pixel.rgbRed   *= bright

pixel += len(RGBQUAD)
' this is to keep track for bright
x++
if (x = bmp.bmWidth)
x = 0
endif
NEXT i

elseif (bmp.bmBitsPixel = 24)

settype pixel, RGBTRIPLE
x = 0

FOR i=1 TO pixelcount

bright = (bmp.bmWidth-x) * fWidth
*pixel.rgbtBlue  *= bright
*pixel.rgbtGreen *= bright
*pixel.rgbtRed   *= bright

pixel += len(RGBTRIPLE)
x++
if (x = bmp.bmWidth)
x = 0
' next line aligned to WORD
pixel += (pixel & 1)
endif
NEXT i

else
endif
' set the bitmap info
_SetBitmapBits(hbitmap, datalen, buffer)
FreeHeap(buffer)
ENDSUB

fasecero

waaaw, so amazing!
No doubt, i will play with this code a lot. I couldn’t find a way to get the pixels adequately. Sapero thanks for this example!
The only question that I arise now is if the bmp.bmBitsPixel member is whether 4 or 8, the pixel pointer variable will still point to a RGBTRIPLE structures.

sapero

No, below 24 bpp it may be different. Each bitmap bit may store offset into internal color table instead a real (compressed) color.
http://msdn.microsoft.com/en-us/library/aa930622.aspx

fasecero

I found an example where the function _GetDIBColorTable  is used to get the color table of an 8-bit bitmap, i will try

fasecero

Well, all is hard in 8 bits.
For either 4 or 8 bits i can get only the color table used by the image.
If I can not go through the pixels, there is no way to apply (for example) the variable shadow effect, but yes i can aply a constant change, like dark the image.
But it doesn't matter really, while i can use 24 bits images :)



' dark a 4 or 8 bits image, not so useful
SUB ImageFilter8bits(uint hdc, uint hbitmap)

BITMAP bmp
pointer buffer
INT hbmold, nColors

hbmold=_SelectObject(hdc, hbitmap)

' get the bitmap info
_GetObject(hbitmap, LEN(bmp), &bmp)

' get the pixels
nColors=2^bmp.bmBitsPixel
buffer= NEW(RGBQUAD, nColors)
_GetDIBColorTable(hdc, 0, nColors, buffer)

' do something with the pixels
pointer pixel : settype pixel, RGBQUAD
bright = 0.5 ' constant value :(
FOR i=1 TO nColors

pixel=#<RGBQUAD>buffer[i-1]
#pixel.rgbBlue  = #pixel.rgbBlue*bright
#pixel.rgbGreen = #pixel.rgbGreen*bright
#pixel.rgbRed   = #pixel.rgbRed*bright
NEXT i

' set the bitmap info
_SetDIBColorTable(hdc, 0, nColors, buffer)

' clean
DELETE buffer
_SelectObject(hdc, hbmold)
ENDSUB



Ionic Wind Support Team

fasecero,
You can get the pixels in an 8 bit image, but they are stored as indexes (4 or 8 bit) into the color table, not 32 bit color values.

4 bits  = Bitmap has a maximum of 16 colors. Each pixel in the bitmap is
represented by a 4-bit index into the color table. For example, if the first
byte in the bitmap is 0x1F, the byte represents two pixels. The first pixel
contains the color in the second table entry, and the second pixel contains
the color in the sixteenth table entry.

8 bits = Bitmap has a maximum of 256 colors. Each pixel in the bitmap is
represented by a 1-byte index into the color table. For example, if the first
byte in the bitmap is 0x1F, the first pixel has the color of the
thirty-second table entry.

Obviously manipulating a 4 or 8 bit bitmap involves changing both the color table and the indexes.  For example if you wanted to change all red pixels to blue you could either swap the entries in the color table, or change the indexes in the bitmap.

Paul.
Ionic Wind Support Team

fasecero

Paul thanks for the information. I will stay at 24 bits, because I find very uncomfortable that every time I change one color will be changed many pixels of the image. In addition, 256 colors is very restrictive.
My only fear is to get one day a device context that supports up to 256 colors.