CPU-Auslastung beim Erstellen von Screenshots



  • Hallo Leute,
    beim Erstellen von Screenshots entsteht leider durch mein Programm eine sehr hohe CPU-Auslastung 😞
    Mein Programm muss allerdings sehr oft Screenshots erstellen, jedoch sollte man am Computer noch mit Freude weiterarbeiten können... Was kann ich also tun?

    bool screenshot(HWND hwnd, const char *filename) {
    	int     nWidth  = GetSystemMetrics(SM_CXSCREEN);
    	int     nHeight = GetSystemMetrics(SM_CYSCREEN);
    
    	HDC     hdc     = GetDC(hwnd);
    	HDC     memDC   = CreateCompatibleDC(hdc);
    	HBITMAP hbm     = CreateCompatibleBitmap(hdc, nWidth, nHeight);
    	HBITMAP hbmOld  = (HBITMAP)SelectObject(memDC, hbm);
    
    	BitBlt(memDC, 0, 0, nWidth, nHeight, hdc, 0, 0, SRCCOPY);
    
    	BITMAPINFO bmi;
    
    	ZeroMemory(&bmi, sizeof(bmi));
    
    	bmi.bmiHeader.biSize         = sizeof(BITMAPINFOHEADER);
    	bmi.bmiHeader.biWidth        = nWidth;
    	bmi.bmiHeader.biHeight       = nHeight;
    	bmi.bmiHeader.biBitCount     = 24;
    	bmi.bmiHeader.biPlanes       = 1;
    	bmi.bmiHeader.biCompression  = BI_RGB;
    	bmi.bmiHeader.biSizeImage    = bmi.bmiHeader.biBitCount * nWidth * nHeight / 8;
    
    	BYTE *pbBits = new BYTE[bmi.bmiHeader.biSizeImage];
    
    	GetDIBits( memDC, 
    				 hbm,
    				 0,
    				 bmi.bmiHeader.biHeight,
    				 pbBits,
    				 &bmi,
    				 DIB_RGB_COLORS );
    
    				BITMAPFILEHEADER bfh;
    
    				bfh.bfType      = ('M' << 8) + 'B';
    				bfh.bfSize      = sizeof(BITMAPFILEHEADER)  +
    								  bmi.bmiHeader.biSizeImage +
    								  sizeof(BITMAPINFOHEADER); 
    				bfh.bfReserved1 = 0;
    				bfh.bfReserved2 = 0;
    				bfh.bfOffBits   = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    
    				HANDLE hfile = CreateFile( filename,
    										   GENERIC_WRITE,
    										   0,
    										   0,
    										   OPEN_ALWAYS,
    										   0,
    										   0 ); 
    
    				DWORD dwWritten;
    
    				WriteFile(hfile,&bfh,           sizeof(bfh),               &dwWritten, NULL); 
    				WriteFile(hfile,&bmi.bmiHeader, sizeof(BITMAPINFOHEADER),  &dwWritten, NULL); 
    				WriteFile(hfile,pbBits,         bmi.bmiHeader.biSizeImage, &dwWritten, NULL); 
    
    				CloseHandle(hfile); 
    
    				SelectObject(memDC, hbmOld);
    				DeleteDC(memDC);
    				ReleaseDC(hwnd,hdc); 
    				DeleteObject(hbm);
    
    				delete[] pbBits;
    				return true;
    }
    

    Vielen Dank im Voraus!

    MrScreenshot



  • **
    Verzeihung!

    Das war der Code den ich zu Testzwecken ausprobiert hatte.
    Dies ist der richtige Code den ich zur Zeit nutze und bei dem das beschriebene Problem auftritt!
    **

    /*
     !!! DER RICHTIGE CODE !!!
    */
    bool screenshot(HWND hwnd, const char *filename) {
    	RECT rt;
    	HDC hdc = GetWindowDC(hwnd);
    	GetWindowRect(hwnd, &rt);
    	int width = rt.right - rt.left;
    	int height = rt.bottom - rt.top;
    
    	HDC hdc2;
    	HBITMAP aBmp;
    	BITMAPINFO bi;
    	HGDIOBJ OldObj;
    
    	void *dibvalues;
    
    	HANDLE fileHandle;
    
    	BITMAPFILEHEADER bmfh;
    	BITMAPINFOHEADER bmih;
    	DWORD bytes_write;
    	DWORD bytes_written;
    
    	hdc2 = CreateCompatibleDC(hdc);
    
    	ZeroMemory(&bmih,sizeof(BITMAPINFOHEADER));
    
    	bmih.biSize=sizeof(BITMAPINFOHEADER);
    	bmih.biHeight=height;
    	bmih.biWidth=width;
    	bmih.biPlanes=1;
    	bmih.biBitCount=24;
    	bmih.biCompression = BI_RGB;
    	bmih.biSizeImage = ((((bmih.biWidth * bmih.biBitCount) + 31) & ~31) >> 3) * bmih.biHeight;
    	bmih.biXPelsPerMeter = 0;
    	bmih.biYPelsPerMeter = 0;
    	bmih.biClrImportant = 0;
    
    	bi.bmiHeader = bmih;
    
    	aBmp = CreateDIBSection(hdc,&bi,DIB_RGB_COLORS,(void**)&dibvalues,NULL,NULL);
    
    	if (!aBmp) {
    		return false;
    	}
    
    	OldObj = SelectObject(hdc2,aBmp);
    
    	BitBlt(hdc2,0,0,width,height,hdc,0,0,SRCCOPY);
    
    	ZeroMemory(&bmfh,sizeof(BITMAPFILEHEADER));
    
    	bmfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
    	bmfh.bfSize = (3*bmih.biHeight*bmih.biWidth)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
    	bmfh.bfType = 0x4d42;
    	bmfh.bfReserved1 = 0;
    	bmfh.bfReserved2 = 0;
    
    	fileHandle=CreateFile(filename,GENERIC_READ | GENERIC_WRITE,(DWORD)0,NULL,
    
    	CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,(HANDLE) NULL);
    
    	if (fileHandle==INVALID_HANDLE_VALUE) {
    		return false;
    	}
    
    	bytes_write = sizeof(BITMAPFILEHEADER);
    
    	if (!WriteFile(fileHandle,(void*)&bmfh,bytes_write,&bytes_written,NULL)) {
    		return false;
    	}
    
    	bytes_write = sizeof(BITMAPINFOHEADER);
    
    	if (!WriteFile(fileHandle,(void*)&bmih,bytes_write,&bytes_written,NULL)) {
    		return false;
    	}
    
    	bytes_write = bmih.biSizeImage;
    
    	if (!WriteFile(fileHandle,(void*)dibvalues,bytes_write,&bytes_written,NULL)) {
    		return false;
    	}
    
    	CloseHandle(fileHandle);
    
    	DeleteObject(SelectObject(hdc2,OldObj));
    	DeleteDC(hdc2);
    	ReleaseDC(hwnd,hdc); 
    
    	return true;
    }
    

    Nochmals Vielen Dank im Voraus!

    MrScreenshot



  • kein problem, einfach dual core rechner nutzen und das programm auf dem 2ten prozessor laufen lassen, dann kannst du sogar vom "Program das viele Screenshots erstellen muß" zum Echtzeitcapturen des Screens übergehn und Dir dein Werkeln später als Film angucken 😉

    Grüße



  • Omg, ich hoffe du meintest das gerade nicht wirklich ernst.



  • Man könnte z.B. CreateDIBSection() nur 1x aufrufen und die erzeugte DIB-Section immer wieder verwenden statt bei jedem Screenshot neu aufzurufen. Genauso die BITMAPFILEHEADER-Struktur etc. sofern sich an der Bildgröße nichts ändert...


Anmelden zum Antworten