Bildschirminhalt in Bitmap speichern
-
Da es ja einige Noobs immer noch nicht verstehen, wie man den Bildschirminhalt
in eine Bitmap speichert, schreibe ich hier mal einige Zeilen Code dazu:
(Jaja... den allergrößten Teil habe ich aus dem FAQ - aber dort wird nicht beschrieben, wie man die Funktion aufruft
)Für 1024 und 768 müsst Ihr selbstverständlich eure Bildschirmhöhe -und Breite einsetzen

#include "windows.h" int dc2bitmap(HDC hdc, int width, int height, char *filename); int WINAPI WinMain (HINSTANCE hI, HINSTANCE hPrI, PSTR szCmdLine, int iCmdShow) { char *filename="desk.bmp"; HDC hdc=GetDC(NULL); dc2bitmap(hdc, 1024, 768, filename); return 0; } int dc2bitmap(HDC hdc, int width, int height, char *filename) { 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; //bmih.biSizeImage=(3*bmih.biHeight*bmih.biWidth); //bmih.biSizeImage = 0; bi.bmiHeader=bmih; aBmp=CreateDIBSection(hdc,&bi,DIB_RGB_COLORS,(void**)&dibvalues,NULL,NULL); if (aBmp==NULL) {return 0;} 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 0; } // Write the BITMAPFILEHEADER bytes_write=sizeof(BITMAPFILEHEADER); if (!WriteFile(fileHandle,(void*)&bmfh,bytes_write,&bytes_written,NULL)) {return 0;} //Write the BITMAPINFOHEADER bytes_write=sizeof(BITMAPINFOHEADER); if (!WriteFile(fileHandle,(void*)&bmih,bytes_write,&bytes_written,NULL)) {return 0;} //Write the Color Index Array??? bytes_write=bmih.biSizeImage;//3*bmih.biHeight*bmih.biWidth; if (!WriteFile(fileHandle,(void*)dibvalues,bytes_write,&bytes_written,NULL)) {return 0;} CloseHandle(fileHandle); DeleteObject(SelectObject(hdc2,OldObj)); DeleteDC(hdc2); return 1; }
-
Also das Aufrufen der Funktion sollte man auch so eigentlich hinbekommen

-
Fehlt da nicht ein
DeleteDC(hdc);
???

-
Nein ein ReleaseDC(hdc);
Also flenders wie war das doch gleich :p
-
Desweiteren ist die Zeile
char *filename="desk.bmp";mehr als gewagt...
Wenn das CurrentDirectory nicht grad zufälligerweise das der eigenen Anwendung ist, sucht man sich hinterher dumm und dusselig nach dem Bild, was werweißwo gespeichert sein kann.
Besser wäre es da, einen absoluten Pfad anzugeben (z. B. sich vorher den ModuleName und FullPath zur eigenen Anwendung zu holen, Anwendungsnamen entfernen und dann den Bildnamen.bmp dranhängen).
-
@D@niel $chumann: Deine Bemerkung verstehe ich irgendwie nicht so ganz

-
Ich verstehe das so das Du meinst man sollte eigentlich wissen, wie man eine Funktion aufruft, der Threadstarter es mit dem Funktionen aufrufen aber selber nicht so richtig beherrscht...
-
Achso - würde Sinn machen

-
Nur leider kann ich das bmp nicht in Paint öffnen. der speichert irgendwie den Header nicht richtig.
-
und du verwendest genau den obenstehenden Code (bzw. mit eingefügtem ReleaseDC(hdc); )?! Bei mir gibt es da nämlich keinerlei Probleme
