Thread: Optimization possible? - Screenshot

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    166

    Optimization possible? - Screenshot

    Hi, I have this function for taking a screenshot and extracting the pixels, it is working but I have a feeling it could be optimized and I don't really know what all the commands do. Can you spot any superflous steps or any other issues?
    Code:
    bool GetScreenshot()
    {
    	int screenWidth = GetSystemMetrics(SM_CXSCREEN);
    	int screenHeight = GetSystemMetrics(SM_CYSCREEN);
    
    	HDC hdcScreen = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
    	HDC hdcShot = CreateCompatibleDC(hdcScreen);
    	HBITMAP hbmap = CreateCompatibleBitmap(hdcScreen, screenWidth, screenHeight);
    	HBITMAP hBitmapOld = (HBITMAP) SelectObject(hdcShot, hbmap);
    	BitBlt(hdcShot, 0, 0, screenWidth, screenHeight, hdcScreen, 0, 0, SRCCOPY);
    
    	BITMAP bm;
    	if (!GetObject(hbmap, sizeof(BITMAP), (LPSTR)&bm)) return false;
    	int bitsPerPixel = bm.bmBitsPixel;
    	int bwidth = bm.bmWidth;
    	int bheight = bm.bmHeight;
    
    	if (bitsPerPixel != 32 || bm.bmPlanes != 1) return false;
    
    	BITMAPINFO bmi;
    	bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    	bmi.bmiHeader.biWidth = bwidth;
    	bmi.bmiHeader.biHeight = bheight;
    	bmi.bmiHeader.biPlanes = 1;
    	bmi.bmiHeader.biBitCount = bitsPerPixel;
    	bmi.bmiHeader.biCompression = BI_RGB;
    	bmi.bmiHeader.biSizeImage = 0;
    
    	BYTE* bits = new BYTE[bwidth * bheight * 4];
    	if (!bits) return false;
    
    	HDC hdc = GetDC(GetDesktopWindow());
    	if (!GetDIBits(hdc, hbmap, 0, bheight, bits, &bmi, DIB_RGB_COLORS))
    	{
    		ReleaseDC(GetDesktopWindow(), hdc);
                    delete [] bits;
    		return false;
    	}
    	ReleaseDC(GetDesktopWindow(), hdc);
    
    	//Do things with bits here
    
    	SelectObject(hdcShot, hBitmapOld);
    	DeleteObject(hbmap);
    	DeleteDC(hdcShot);
    	DeleteDC(hdcScreen);
    
    	return true;
    }
    Thanks!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    How long does it take to call it once?
    If it's less than say 20mS, then it's already faster than what you can perceive as being "instantaneous" and "taking some time".

    How many times per second are you planning to call it?
    If (X times per second) * (time per grab) is still less than one second, do you still need to do anything?

    What other useful function can you be getting on with coding, rather than focussing on optimisation?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Since you are not using nothrow new, this is superfluous:
    Code:
    if (!bits) return false;
    Rather, std::bad_alloc might be thrown. I suggest that you replace this:
    Code:
    BYTE* bits = new BYTE[bwidth * bheight * 4];
    if (!bits) return false;
    with:
    Code:
    std::vector<BYTE> bits(bwidth * bheight * 4);
    and then change this:
    Code:
    if (!GetDIBits(hdc, hbmap, 0, bheight, bits, &bmi, DIB_RGB_COLORS))
    {
        ReleaseDC(GetDesktopWindow(), hdc);
        delete [] bits;
        return false;
    }
    to:
    Code:
    if (!GetDIBits(hdc, hbmap, 0, bheight, &bits[0], &bmi, DIB_RGB_COLORS))
    {
        ReleaseDC(GetDesktopWindow(), hdc);
        return false;
    }
    This could well fix a potential memory leak in your code.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    I second the earlier changes.

    If you're desperate to make it faster then several of those things could be precalculated in a seperate function, and passed into this function inside an object, each time it is called. However rather than being a useful optimisation, this would probably simply demonstrate that it's not worth trying to make it faster than it is already because there's very little gain left to be made.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Turn Off Optimization?
    By danlee58 in forum C Programming
    Replies: 6
    Last Post: 12-10-2008, 03:52 AM
  2. need reading material for c++ database optimization
    By elninio in forum C++ Programming
    Replies: 0
    Last Post: 07-24-2008, 11:32 PM
  3. optimization flags
    By markucd in forum C++ Programming
    Replies: 4
    Last Post: 06-30-2006, 09:08 AM
  4. Taking Screenshot - Full Screen Dos
    By loko in forum C Programming
    Replies: 12
    Last Post: 07-16-2005, 01:23 AM
  5. Optimization settings
    By Roaring_Tiger in forum C Programming
    Replies: 4
    Last Post: 02-23-2005, 02:53 AM