Sign in to follow this  
SymLinked

Win32 - capturing screenshots and odd resolutions

Recommended Posts

SymLinked    1233
Hi!

I've implemented a simple screenshot capture method, where I do the following:[list=1]
[*]Get the screen DC by calling [i]GetDC (NULL);[/i]
[*]Use [i]CreateCompatibleDC ()[/i] to create a device context.
[*]Grab width/height of the screen by calling [i]GetDeviceCaps ()[/i].
[*]Calling [i]CreateCompatibleBitmap (screenDC, width, height);[/i]
[*][i]Calling SelectObject (deviceContext, bitmap);[/i]
[*]Finally, calling [i]BitBlt (deviceContext, 0, 0, x, y, screenDC, 0, 0, SRCCOPY | CAPTUREBLT);[/i] and [i]GetDIBits ()[/i] to get the data pointer.
[/list]
This works fine except that it doesn't work in odd resolutions like 1366x768 where everything shows up as white/black lines. Anyone got any ideas what's causing this? Is the data output from GetDIBits() padded in this case or something? It looks like there's an extra byte per channel or something which distorts the image as I'm assuming 32-bit, but that's hardly the case as the image is 32-bit.

Any advice is greatly appreciated!

Share this post


Link to post
Share on other sites
frob    44904
Read up a little about the bitmap format.

The format has some details that you may have missed.

The data probably IS NOT CONTINUOUS.

Every pixel entry can potentially have some unused space on it; as you noticed only 24 bits are valid but 32 bits are used. Every scan line may potentially have some unused space on it. e.g. The data may have space for 1024 but the window is only 1022 pixels long.

You need to account for both.

Share this post


Link to post
Share on other sites
SymLinked    1233
That sounds logical, but how exactly would you detect when this happens? It's definatly not different bitrates, I already account for that - it's something else.
I've Googled and Googled but come up with nothing.

I retrieve the width, height, numBits and format but it looks exactly the same as in all other resolutions.

Share this post


Link to post
Share on other sites
SymLinked    1233
Just a memory copy, which works in all other resolutions I've tested except 1366x768. Even the bitmap header says the size of the lpvBits data is what I expected (ie, 4 * width * height) so I'm not sure how I would be able to read it any differently.

Share this post


Link to post
Share on other sites
Amr0    2230
Yes the symptoms conform with padding unaccounted for. In addition to per-pixel padding, the BMP format uses per-row padding. You can calculate the number of bytes used per row of pixels like so:
[CODE]
rowSize = DWordAlign( bpp/8 * width );
[/CODE]
[size=2]You may find these useful: Mirror: [url="http://my.opera.com/adelamro/blog/2010/03/21/mirror"]GDI-based mirror window[/url] (src code included), [url="http://my.opera.com/adelamro/blog/gdi-memory-bitmap"]GDI Memory Bitmap[/url][/size] Edited by Amr0

Share this post


Link to post
Share on other sites
SymLinked    1233
Thanks Amr0!

But the return value of DWordAlign with the argument of (32 / 8 * 1366) is the same as the argument so it has no effect.
GDI Memory Bitmap is a very useful resource though, I'll keep poking and see what's different from your implementation!

Thanks again. Edited by SymLinked

Share this post


Link to post
Share on other sites
SymLinked    1233
If you have 4 bytes per pixel, and are using a 1366 width - everything is already aligned to 4 bytes. It would have been different if it was 3 bytes per pixel but that's not the case here.
I'm still looking for suggestions. (Edit: Fixed. See my last response for solution)

[img]http://www.gameinprogress.com/gamedev/1366x768.jpg[/img] Edited by SymLinked

Share this post


Link to post
Share on other sites
Bacterius    13165
Code, please. Without the actual details of how you obtain this result we can't do any better than vaguely theorize on why you aren't getting what you want. The shearing clearly indicates you are getting out of sync with the pixels on a per-row basis, and the color corruption is just weird.

Share this post


Link to post
Share on other sites
frob    44904
The image sheering looks like a textbook example of not accounting for the row length. Each row has a few pixels from the next row, causing the row below it to be shifted a few pixels.

Share this post


Link to post
Share on other sites
SymLinked    1233
Thanks Baterius, I was about to do that but figured it out now.

The above mentioned resources are correct and I'll edit my response. The error was my fault and was caused by me assuming FreeImage would just accept my buffer as is, without calling SetPixelColor() on each individual pixel. The latter works which I guess means I have to read up on how FreeImage stores its bitmaps instead.

Sorry for the misinformation on my side. Everything claimed so far was correct, I was just looking in the wrong spot. Edited by SymLinked

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this