🔒 Locked
Bitmaps
Advertisement
Original Post
Hey, Im using some AVI functions to get a specified frame from an AVI video. That function returns a pointer to a BITMAPINFO object. Looks like this:
LPBITMAPINFO mybitmap = (LPBITMAPINFO)AVIStreamGetFrame(blablabla);
The problem though, is I cant find where the pixel data is stored in this bitmap structure thing :s
Ive tried using mybitmap->bmiColors[pixeloffset].rgbRed, rgbBlue, and rgbGreen to get the color values value for a certian offset, but I guess the bmiColors structure does not contain the pixel data because I get about 10 colors and the rest is black. (btw, I calculate the offset for a pixel like this: offset=imagewidth*y+x)
So, my question, How do I obtain the pixel values from a pointer to a LPBITMAPINFO object?
Thanks
Or could it be that the bmiColors array doesn''t contain just the linear pixel color values?
are you sure you are supposed to somehow get pixel data with this function?
a BITMAPINFO structure is what the name says...it just contains information about the bitmap, like size and stuff in the structures bmiHeader part.
the bmiColors part just contains color info. In a 24 bit bmp it is NULL, that's propably where your errors come from.
but a BITMAPINFO structure contains not the actual image data. perhaps you should check the docs of your AVI Api again.
Edit: Actually i just did it myself and the prototype for the function according to MSDN is
STDAPI_(LPVOID) AVIStreamGetFrame(
PGETFRAME pgf,
LONG lPos
);
so don't try converting the void* to a BITMAPINFO* there. It says the void* points to a packed DIB.
Runicsoft -- home of my open source Function Parser and more
[edited by - Burning_Ice on November 28, 2002 4:25:00 PM]
a BITMAPINFO structure is what the name says...it just contains information about the bitmap, like size and stuff in the structures bmiHeader part.
the bmiColors part just contains color info. In a 24 bit bmp it is NULL, that's propably where your errors come from.
but a BITMAPINFO structure contains not the actual image data. perhaps you should check the docs of your AVI Api again.
Edit: Actually i just did it myself and the prototype for the function according to MSDN is
STDAPI_(LPVOID) AVIStreamGetFrame(
PGETFRAME pgf,
LONG lPos
);
so don't try converting the void* to a BITMAPINFO* there. It says the void* points to a packed DIB.
Runicsoft -- home of my open source Function Parser and more
[edited by - Burning_Ice on November 28, 2002 4:25:00 PM]
quote:
Original post by Burning_Ice
a BITMAPINFO structure is what the name says...it just contains information about the bitmap, like size and stuff in the structures bmiHeader part.
this is correct. however, a pointer to bitmapinfo structure can also be used to get to the bitmap bits, which you missed.
quote:
the bmiColors part just contains color info. In a 24 bit bmp it is NULL, that''s propably where your errors come from.
[quote]
since it''s a variable-length array, and not a pointer, it can never be null.
[quote]
but a BITMAPINFO structure contains not the actual image data.
it doesn''t; image data immediately follows it.
quote:
msdn: bitmapinfo
A bitmap is packed when the bitmap array immediately follows the BITMAPINFO header.
quote:
perhaps you should check the docs of your AVI Api again.
perhaps you should check the docs so that you actually have a clue what you''re talking about.
quote:
Actually i just did it myself
surely you have a program that doesn''t work that you can show us?
quote:
so don''t try converting the void* to a BITMAPINFO* there. It says the void* points to a packed DIB.
now open that page again and read remarks this time.
now to OP:
first, determine how big the color table (palette) is. for a true-color bitmap, it should have two dummy elements so that bitmap data is dword-aligned, or it may be nonexistent. once you know that, a pointer just after the color table will point to bitmap bits.
quote:
this is correct. however, a pointer to bitmapinfo structure can also be used to get to the bitmap bits, which you missed.
a BITMAPINFO structure alone still can not be used for it. only if you have a complete DIB there's the image data behind this structure, that's what i tried to say
quote:
since it's a variable-length array, and not a pointer, it can never be null.
please check MSDN, it says:
"The bitmap has a maximum of 2^24 colors, and the bmiColors member is NULL. Each 3-byte triplet in the bitmap array represents the relative intensities of blue, green, and red, respectively, for a pixel. "
quote:
surely you have a program that doesn't work that you can show us?
if you would have taken the time to read my post you would have noticed that my last sentence was
"perhaps you should check the docs again"
and my Edit said that i just did it (check the docs! not code anything), where i could see that indeed the function does not return a LPBITMAPINFO but a LPVOID.
quote:
now open that page again and read remarks this time.
okok, so i admit that i just tried to write a helping post and not read the entire docs again, but my point was (sorry if i wasn't clear enough):
The function does not return a LPBITMAPINFO. It returns a pointer to a packed DIB. So the actual data is after the info struct, but you can't get any image data out of the info struct itself.
That's all i wanted to say. I don't understand why that made you so angry, but i apologize anyway.
The 'you should check the docs again' was in no way meant unfriendly, i just said this because i thought that there has to be an error if ALL the function returns would be a pointer to a BITMAPINFO.
But as it is it returns more then the info struct, so its all ok now i hope.
Runicsoft -- home of my open source Function Parser and more
[edited by - Burning_Ice on November 28, 2002 5:39:19 PM]
Well, Im kinda confused about whos saying what, but thanks! So basicaly, to get the bitmap data, you just have to get a pointer to the data right after the bmpinfo structure?
Anyways, to get that pointer would I haveto do something like this?
char *pBMPData;
pBMPData=&bmpinfo+sizeof(bmpinfo);
Anyways, to get that pointer would I haveto do something like this?
char *pBMPData;
pBMPData=&bmpinfo+sizeof(bmpinfo);
Yep. The bitmap header gives you information about the frame, and the bit data follows it.
From the MSDN:
So you can use that to see if there is a colour table, and how large it is.
From the MSDN:
quote:
If the bitmap is a packed bitmap (a bitmap in which the bitmap array immediately follows the BITMAPINFO header and is referenced by a single pointer), the biClrUsed member must be either zero or the actual size of the color table.
So you can use that to see if there is a colour table, and how large it is.
Is that from the MSDN site? I''ve been using the MSDN cd''s to do this stuff. I guess what Im trying to do is make a program that takes homevideo stuff and applys some filters and motion blur to make a video taken from a camcorder look like something taken from a film movie camera
So, uhh, would this work to give me a pointer to the pixel data? (Im kinda a c++ N00bie)
LPVOID bmpinfo = (LPVOID)AVIStreamGetFrame(blablabla);
char *pData; //Pointer to pixel data?
pData=&bmpinfo+sizeof(bmpinfo);
LPVOID bmpinfo = (LPVOID)AVIStreamGetFrame(blablabla);
char *pData; //Pointer to pixel data?
pData=&bmpinfo+sizeof(bmpinfo);
Wait, uhh I dont think that would work.
Would it be more like this?
LPBMPINFO bmpinfo (LPBMPINFO)AVIStreamGetFrame(...);
char *pData;
pData=&bmpinfo+bmpinfo->bmiHeader.biSize;
Ehh I dunno, I have no idea what I''m doing :-\
Would it be more like this?
LPBMPINFO bmpinfo (LPBMPINFO)AVIStreamGetFrame(...);
char *pData;
pData=&bmpinfo+bmpinfo->bmiHeader.biSize;
Ehh I dunno, I have no idea what I''m doing :-\
That quote was from the MSDN CDs (under BITMAPINFOHEADER).
i think is right, but to be honest i''m not sure. It looks right anyway. The best thing to do is give it a try and find out.
LPBMPINFO bmpinfo (LPBMPINFO)AVIStreamGetFrame(...);
char *pData;
pData=&bmpinfo+bmpinfo->bmiHeader.biSize
i think is right, but to be honest i''m not sure. It looks right anyway. The best thing to do is give it a try and find out.
I did this and it works just fine 
LPBITMAPINFOHEADER bmpinfo = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pgf,lFrame); // returns NULL if error
BYTE *pdata = (BYTE *)bmpinfo + (bmpinfo->biSize + bmpinfo->biClrUsed * sizeof(RGBQUAD));
Butttt, Im kinda stuck again (whatta surprise), would *pdata be an array of data? Or is *pdata just the first byte of the pixel data? I tried using this just to try to display the bitmap or at least get colors, but it was all black :-/
for(int x=0;x<321;x++) {
for(int y=0;y<321;y++){
int r=*pdata;
pdata++;
int g=*pdata;
pdata++;
int b=*pdata;
pdata++;
SetPixel(GetDC(ghwnd),x,y,RGB(r,g,b));
}
}
LPBITMAPINFOHEADER bmpinfo = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pgf,lFrame); // returns NULL if error
BYTE *pdata = (BYTE *)bmpinfo + (bmpinfo->biSize + bmpinfo->biClrUsed * sizeof(RGBQUAD));
Butttt, Im kinda stuck again (whatta surprise), would *pdata be an array of data? Or is *pdata just the first byte of the pixel data? I tried using this just to try to display the bitmap or at least get colors, but it was all black :-/
for(int x=0;x<321;x++) {
for(int y=0;y<321;y++){
int r=*pdata;
pdata++;
int g=*pdata;
pdata++;
int b=*pdata;
pdata++;
SetPixel(GetDC(ghwnd),x,y,RGB(r,g,b));
}
}
Hm... Then I did this:
for(int x=0;x<321;x++) {
for(int y=0;y<321;y++){
char buffer[255];
sprintf(buffer,"%i ",*pdata);
pdata++;
sprintf(buffer,"%i ",*pdata);
OutputDebugString(buffer);
pdata++;
sprintf(buffer,"%i ",*pdata);
OutputDebugString(buffer);
pdata++;
OutputDebugString(buffer);
//SetPixel(GetDC(ghwnd),x,y,RGB(r,g,b));
}
}
I got a lot of 10''s, 11''s, 12''s, 13''s, and a few larger #''s in the 200''s or so. And then, when x reached 110 and y reached 156, I got an access violation error :|
for(int x=0;x<321;x++) {
for(int y=0;y<321;y++){
char buffer[255];
sprintf(buffer,"%i ",*pdata);
pdata++;
sprintf(buffer,"%i ",*pdata);
OutputDebugString(buffer);
pdata++;
sprintf(buffer,"%i ",*pdata);
OutputDebugString(buffer);
pdata++;
OutputDebugString(buffer);
//SetPixel(GetDC(ghwnd),x,y,RGB(r,g,b));
}
}
I got a lot of 10''s, 11''s, 12''s, 13''s, and a few larger #''s in the 200''s or so. And then, when x reached 110 and y reached 156, I got an access violation error :|
I don't know about that problem, but theres a couple of errors there:
1) the returned data is an array of RGBQUADs, but you're only extracting 3 bytes (instead of 4). You should either cast pdata to an RGBQUAD*, or add another pdata++ at the end of your 'y' loop.
2)You should be calling ReleaseDC() for every call to GetDC() otherwise you might eat system resources, and cause GetDC() to fail (which would likely result in not writing any anything - i.e. blackness).
What are you SetPixel()ing for? Is this just in your window? Is this MFC? Dialog based or Single Docuument?
At least you're not getting any access violations
Edit: Ok, *now* you're getting access violations

[edited by - Evil Bill on November 29, 2002 3:12:32 PM]
1) the returned data is an array of RGBQUADs, but you're only extracting 3 bytes (instead of 4). You should either cast pdata to an RGBQUAD*, or add another pdata++ at the end of your 'y' loop.
2)You should be calling ReleaseDC() for every call to GetDC() otherwise you might eat system resources, and cause GetDC() to fail (which would likely result in not writing any anything - i.e. blackness).
What are you SetPixel()ing for? Is this just in your window? Is this MFC? Dialog based or Single Docuument?
At least you're not getting any access violations
Edit: Ok, *now* you're getting access violations

[edited by - Evil Bill on November 29, 2002 3:12:32 PM]
Just been looking at the MSDN. Shouldn''t you be using the DrawDib functions to draw the frame (DrawDibOpen, DrawDibBegin, DrawDibDraw, etc)?
Looking at this
Looking at this
Well, I did use the DIBSetToDevice or whatever to draaw the image to my window (not MFC). But, I don''t really need to draw the stuff to the window, I just need the pixel color values for what Im doing. Uhh when I did use the DibSetToDevice or whatever, this happened :| http://www.lancecoders.com/avi.JPG
Are you sure I am trying to use an RGBQUAD? When I use this, BYTE *pdata = (BYTE *)bmpinfo + (bmpinfo->biSize + bmpinfo->biClrUsed * sizeof(RGBQUAD));
, Aren''t I suppose to be getting a pointer to just the plain bitmap data? oR is the RGBQUAD the bitmap data? :s
PERSON *Matt;
Matt->State="CONFUSED";
Matt->EatCandy(CANDY_BUTTERFINGER);
Are you sure I am trying to use an RGBQUAD? When I use this, BYTE *pdata = (BYTE *)bmpinfo + (bmpinfo->biSize + bmpinfo->biClrUsed * sizeof(RGBQUAD));
, Aren''t I suppose to be getting a pointer to just the plain bitmap data? oR is the RGBQUAD the bitmap data? :s
PERSON *Matt;
Matt->State="CONFUSED";
Matt->EatCandy(CANDY_BUTTERFINGER);
Well basically what I was doing was just trying to extract all the pixel information so I could manipulate it (apply filters and effects) and then put it back into the AVI.
I guess its possible that Its trying to use a pallete, so I''ll see if I can mess around with that and get it to work
I guess its possible that Its trying to use a pallete, so I''ll see if I can mess around with that and get it to work
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement