Win32 Erstellen Bitmap von einem Device Context eine Datei und/oder BLOB -
Ich würde gerne den Rahmen meines Fensters in ein bitmap. Ich benutzen das Fenster zu ziehen basic-Zeilen mit touch. Das problem, dass ich habe ist meine bitmap ist schwarz. Denen ist es wahrscheinlich aufgrund der Tatsache, dass ich nicht greifen, das Gerät Kontext richtig oder mache etwas anderes falsch.
Die Funktionen CreateBitmapInfoStruct
und CreateBMPFile
sind aus das MSDN-Beispiel.
Beachten Sie auch, dass g_hWnd
ist eine Globale variable, die das handle des Fensters, für das ich möchte das Bild speichern.
Mein end-Ziel ist es, in der Lage sein, speichern Sie die bitmap in eine mysql-Feld (BLOB), die ich habe. Dies ist, was mein ursprüngliches problem war. Wie auch immer, ich begann, indem Sie zuerst versuchen, um eine BMP-Datei.
Habe ich danach gesucht, hier und in anderen Orten. Die beste Lösung, die ich gefunden wurde empfohlen, hier folgende das MSDN-Beispiel. Es ist jedoch nicht arbeiten.
Jede Hilfe für dieses spezifische problem und/oder schriftlich an die bitmap in ein blob in der mysql-Tabelle, wird sehr geschätzt.
Hier ist mein code:
HDC hDC = GetDC(g_hWnd);
LPRECT rect = (LPRECT)malloc(sizeof(RECT));
GetWindowRect(g_hWnd,rect);
int h = rect->right - rect->left;
int w = rect->bottom - rect->top;
LPRECT rect = (LPRECT)malloc(sizeof(RECT));
GetWindowRect(g_hWnd,rect);
HBITMAP hBmp = CreateCompatibleBitmap(hDC,w,h);
PBITMAPINFO pbmi;
pbmi = CreateBitmapInfoStruct(g_hWnd,hBmp);
CreateBMPFile(g_hWnd, TEXT("c:\\TEMPO\\TestG2.bmp"), pbmi,
hBmp, hDC) ;
ReleaseDC(g_hWnd,hDC);
DeleteObject(hBmp);
DeleteObject(pbmi);
if (rect != nullptr)
free(rect);
EDIT:
Die eigentliche Antwort für die Erfassung der Bildschirm (getDC) ist zu ändern das Beispiel in der MSDN.
Habe ich geändert, das Beispiel hier (entfernen Sie die stretch) Hinweis, dass noch mit dem "goto", die ich entfernen.
Eine Anmerkung zu SPRINGEN... Und ich benutze es nicht, ich finde nicht, dass es ein problem entweder. Ich denke, zu viel wurde über die GOTO-Anweisung... ist wie wenn in der Versammlung, würden wir nicht springen (SPRINGT)
Hier ist der code:
void saveBitmap()
{
HDC hdcScreen;
HDC hdcWindow;
HDC hdcMemDC = NULL;
HBITMAP hbmScreen = NULL;
BITMAP bmpScreen;
//Retrieve the handle to a display device context for the client
//area of the window.
hdcScreen = GetDC(NULL);
hdcWindow = GetDC(g_hWnd);
//Create a compatible DC which is used in a BitBlt from the window DC
hdcMemDC = CreateCompatibleDC(hdcWindow);
if(!hdcMemDC)
{
goto done;
}
RECT rcClient;
GetClientRect(g_hWnd, &rcClient);
hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right-rcClient.left,
rcClient.bottom-rcClient.top);
if(!hbmScreen)
{
goto done;
}
SelectObject(hdcMemDC,hbmScreen);
if(!BitBlt(hdcMemDC,
0,0,
rcClient.right-rcClient.left, rcClient.bottom-rcClient.top,
hdcWindow,
0,0,
SRCCOPY))
{
goto done;
}
GetObject(hbmScreen,sizeof(BITMAP),&bmpScreen);
BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bmpScreen.bmWidth;
bi.biHeight = bmpScreen.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 *
bmpScreen.bmHeight;
//Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that
//call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc
//have greater overhead than HeapAlloc.
HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize);
char *lpbitmap = (char *)GlobalLock(hDIB);
//Gets the "bits" from the bitmap and copies them into a buffer
//which is pointed to by lpbitmap.
GetDIBits(hdcWindow, hbmScreen, 0,
(UINT)bmpScreen.bmHeight,
lpbitmap,
(BITMAPINFO *)&bi, DIB_RGB_COLORS);
//A file is created, this is where we will save the screen capture.
HANDLE hFile = CreateFile(L"c:\\tempo\\captureqwsx.bmp",
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
//Add the size of the headers to the size of the bitmap to get the total file size
DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) +
sizeof(BITMAPINFOHEADER);
//Offset to where the actual bitmap bits start.
bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) +
(DWORD)sizeof(BITMAPINFOHEADER);
//Size of the file
bmfHeader.bfSize = dwSizeofDIB;
//bfType must always be BM for Bitmaps
bmfHeader.bfType = 0x4D42; //BM
DWORD dwBytesWritten = 0;
WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
//Unlock and Free the DIB from the heap
GlobalUnlock(hDIB);
GlobalFree(hDIB);
//Close the handle for the file that was created
CloseHandle(hFile);
//Clean up
done:
DeleteObject(hbmScreen);
DeleteObject(hdcMemDC);
ReleaseDC(NULL,hdcScreen);
ReleaseDC(g_hWnd,hdcWindow);
}
if (rect != nullptr)
<- was ist nullptr
? Ist, dass eine lokale var? Oder ist dies ein Anzeichen dafür, dass Sie etwas zu tun mit managed C++? Auch, du bist deklarieren rect
zweimal führen würde zu einem compiler-Fehler. Ich würde raten, nicht die Schaffung einer LPRECT
mit malloc
, stattdessen deklarieren Sie eine lokale RECT
auf dem stack und pass &rect
.nullptr ist Teil von c++ 11, die einige Werke in vs 2010. Kein verwalteter code oj
Die lprect deklariert ist doppelt, weil der eine Kopie paste miskake.
AH ja, natürlich. C++11. My bad, danke für die Klarstellung.
InformationsquelleAutor Blues76 | 2012-07-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie GetDIBits().
Diese Funktion kopiert die Bild-Pixel-Daten in Ihrem eigenen Speicher zugewiesen.
Sehen GetDIBits und Schleife über die Pixel mit X -, Y - für einige weitere details und Erklärung.
Eine Frage zu dem Griff: GRIFF hSource = ?Sollte es sein, HBITMAP und wäre es HBITMAP = CreateCompatibleBitmap(...) ?
Laut der Dokumentation ist der zweite parameter ist in der Tat HBITMAP
InformationsquelleAutor Asaf