Solved

BitBlt/StretchBlt color conversion

Posted on 2002-03-07
5
1,123 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

This article shows a few slightly more advanced techniques for Windows 7 gadget programming, including how to save and restore user settings for your gadget and how to populate the "details" panel that is displayed in the Windows 7 gadget gallery.  …
zlib is a free compression library (a DLL) on which the popular gzip utility is built.  In this article, we'll see how to use the zlib functions to compress and decompress data in memory; that is, without needing to use a temporary file.  We'll be c…
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…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …

691 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