Solved

BitBlt/StretchBlt color conversion

Posted on 2002-03-07
5
1,092 Views
Last Modified: 2013-12-04
In my program, it is necessary to convert the screen capture image from the screen's bit depth (usually 32bpp) to a 24bit format. With this code, I get about 0.5 to 1.0 seconds of lag (system freeze; the mouse cannot be moved) during StretchBlt() when converting from my desktop depth of 32bits to 24bits. As far as I can tell, this could perhaps be windows XP dependant?

Here's the code:

HBITMAP Bitmap;
int ScreenWidth, ScreenHeight, Width, Height, Scale;
HDC DesktopDC, CaptureDC;
BITMAPINFO BitmapInfo;
unsigned char *Data;

Scale = 50;
DesktopDC = GetDC(GetDesktopWindow());
ScreenWidth = GetDeviceCaps(DesktopDC, HORZRES);
ScreenHeight = GetDeviceCaps(DesktopDC, VERTRES);
Width = (ScreenWidth * Scale) / 100;
Height = (ScreenHeight * Scale) / 100;

memset(&BitmapInfo.bmiHeader, 0, sizeof(BitmapInfo.bmiHeader));
BitmapInfo.bmiHeader.biWidth = Width;
BitmapInfo.bmiHeader.biHeight = Height;
BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BitmapInfo.bmiHeader.biPlanes = 1;
BitmapInfo.bmiHeader.biBitCount = 24;
BitmapInfo.bmiHeader.biCompression = BI_RGB;

CaptureDC = CreateCompatibleDC(DesktopDC);
Bitmap = CreateDIBSection(DesktopDC, &BitmapInfo, DIB_RGB_COLORS, (void **)&Data, 0, 0);

SelectObject(CaptureDC, Bitmap);
StretchBlt(CaptureDC, 0, 0, Width, Height, DesktopDC, 0, 0, ScreenWidth, ScreenHeight, SRCCOPY); // 1 second freeze occurs here...

Any suggestions? It seems as if StrechBlt() is freezing up due to having to convert from 32bpp to 24bpp. I have the exact same problem when doing BitBlt() from the screen to a bitmap of similar size.
0
Comment
Question by:Olympus
  • 2
  • 2
5 Comments
 
LVL 23

Expert Comment

by:Roshan Davis
ID: 6849730
The problem is not in StreachBlt, or in BitBlt. The lag is due to the bit conversion loop.
HBITMAP Bitmap;
     int ScreenWidth, ScreenHeight, Width, Height, Scale;
     HDC DesktopDC, CaptureDC;
     BITMAPINFO BitmapInfo;
     unsigned char *Data;

     Scale = 50;
     DesktopDC = ::GetDC(::GetDesktopWindow());
     ScreenWidth = GetDeviceCaps(DesktopDC, HORZRES);
     ScreenHeight = GetDeviceCaps(DesktopDC, VERTRES);
     Width = (ScreenWidth * Scale) / 100;
     Height = (ScreenHeight * Scale) / 100;

     memset(&BitmapInfo.bmiHeader, 0, sizeof(BitmapInfo.bmiHeader));
     BitmapInfo.bmiHeader.biWidth = Width;
     BitmapInfo.bmiHeader.biHeight = Height;
     BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
     BitmapInfo.bmiHeader.biPlanes = 1;
     BitmapInfo.bmiHeader.biBitCount = 24;
     BitmapInfo.bmiHeader.biCompression = BI_RGB;

     CaptureDC = CreateCompatibleDC(DesktopDC);
     HBITMAP hCurrentBMP = (HBITMAP)GetCurrentObject(DesktopDC, OBJ_BITMAP);
     Bitmap = CreateDIBSection(DesktopDC, &BitmapInfo, DIB_RGB_COLORS, (void **)&Data, 0, 0);
     DWORD     dw1 = GetTickCount();
     ::GetDIBits(DesktopDC, hCurrentBMP, 0, BitmapInfo.bmiHeader.biHeight, Data, &BitmapInfo, DIB_RGB_COLORS);
     TRACE("Diff = %d \n", GetTickCount() - dw1);
     SelectObject(CaptureDC, Bitmap);

     I think this will get some more performance...
     These things can be apply to avoid the freezing,
     1. U can do ur own converion method and use SetDIBits .. So in that loop u can Peek and Dispatch Message
     2. Do these things in a seperate thread

GOOD LUCK
0
 

Author Comment

by:Olympus
ID: 6851467
Will GetDIBits do the same as BitBlt?
0
 
LVL 23

Expert Comment

by:chensu
ID: 6854930
Have you tried other computers? This could be a hardware design problem. During a Blt operation, the bus is very busy.
0
 

Author Comment

by:Olympus
ID: 6855772
Yes, I have tried on 4 Windows XP computers and 2 Windows 98 computers; all the windows XPs have this problem.
0
 
LVL 23

Accepted Solution

by:
Roshan Davis earned 300 total points
ID: 6855825
GetDIBits gets the bits from the device and can setting this bits to another by SelectObject. This also take some time for the bit conversion, but it less becoz it is from the direct device bitmaps, no memory copying. Try, may have some advantages

GOOD LUCK
0

Featured Post

Does Powershell have you tied up in knots?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article describes how to programmatically preset the "Pages per Sheet" option that's available with most printer drivers.   This setting lets you do "n-Up" printing, where two, four, or more pages are printed on each sheet of paper. If your …
This article describes a technique for converting RTF (Rich Text Format) data to HTML and provides C++ source that does it all in just a few lines of code. Although RTF is coming to be considered a "legacy" format, it is still in common use... po…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question