bild aus der zwischenablage
-
moin,
ein in der zwischenablage befindliches bild soll in eine datei gespeiuchert werden (xxx.bmp)
mein bisheriger code:HANDLE hFile; DWORD dwBytes; if( OpenClipboard(NULL) ) { if( IsClipboardFormatAvailable(CF_BITMAP) ) { HANDLE hClipboardData = GetClipboardData(CF_BITMAP); ??? = GlobalLock(hClipboardData); GlobalUnlock(hClipboardData); if( (hFile = CreateFile("xxx.bmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE ) return 0; if( !WriteFile(hFile, ???, ???, &dwBytes, NULL) ) return 0; CloseHandle(hFile); } CloseClipboard(); }
wie oder in was muss ich das ClipboarData speichern (casten?)
danke
-
schau in der WinAPI FAQ: Bild speichern
....
John
-
FAQ: Bild speichern
Du solltest allerdings erstmal das Handle, welches du von GetClipboardData bekommst per CopyImage() kopieren, denn im SDK steht:The clipboard controls the handle that the GetClipboardData function returns, not the application. The application should copy the data immediately. The application cannot rely on being able to make long-term use of the handle.
-
uuups... Leicht zu spät.
Aber ich hab ja noch ne Zusatzinfo gegeben.
-
@ John || WebFritzi
sorry, aber der link hilft mir irgendwie nicht weiter.
ich will kein DeviceContext(?) speichern sondern den
inhalt der zwischenablage.
-
Wo steht, dass bei dem Link ein DeviceContext gespeichert wird??
Nein, es wird der Inhalt des DeviceContext gespeichert, welcher ein Bitmap ist.
Und nun: Ist der Inhalt Deiner Zwischenablage nicht auch ein Bitmap?
-
Wenn du dein HBITMAP hast, dann machst du das z.B. so:
HBITMAp hBmp; // Irgendwie das Bitmap füllen // Meinetwegen aus der Zwischenablage BITMAP bmp; GetObject(hBmp, sizeof(BITMAP), &bmp); HDC hdc = CreateCompatibleDC(NULL); HBITMAP hOldBmp = SelectObject(hdc, hBmp); dc2bitmap(hdc, bmp.bmWidth, bmp.bmHeight, TEXT("C:\\MyBitmap.bmp")); SelectObject(hdc, hOldBmp); DeleteDC(hdc);
-
pfui
-
Kannst du deine Reaktion auch begründen?
-
man tut das bild direkt speichern.
-
@STRG+C: Hab mit den FAQ Betrag genauer angesehen. Sorry, das mit dem DC wußte ich nicht. Aber so ähnlich geht es.
Die folgende Funktion macht was Du willst, ohne DC.
#define bmAlignDouble(size) ((size + 31) / 32 * 4) int StoreBitmapInFile(LPSTR fileName, HBITMAP hBitmap) { BITMAP bm; BITMAPFILEHEADER bfh; BITMAPINFO *pBmi; HDC hdc; HANDLE hMem; PBYTE pBuf; LONG colorSize, dataSize; WORD bitCount; HANDLE hFile; DWORD nWritten; //-- Get the information about the Bitmap --/ if (GetObject(hBitmap, sizeof(BITMAP), &bm) == 0) return 1; bitCount = bm.bmPlanes * bm.bmBitsPixel; if (bitCount <= 8) colorSize = sizeof(RGBQUAD) * (1 << bitCount); else colorSize = 0; dataSize = bmAlignDouble(bm.bmWidth * bitCount) * bm.bmHeight; //-- Create the file --/ hFile = CreateFile(fileName, GENERIC_WRITE, 0L, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return 2; //-- Allocate memory for the bitmap info structure --/ pBmi = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) + colorSize); if (pBmi != NULL) { //-- Fill in the Bitmap info header --/ pBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pBmi->bmiHeader.biWidth = bm.bmWidth; pBmi->bmiHeader.biHeight = bm.bmHeight; pBmi->bmiHeader.biPlanes = 1; pBmi->bmiHeader.biBitCount = bitCount; pBmi->bmiHeader.biCompression = 0; pBmi->bmiHeader.biSizeImage = dataSize; pBmi->bmiHeader.biXPelsPerMeter = 0; pBmi->bmiHeader.biYPelsPerMeter = 0; pBmi->bmiHeader.biClrUsed = 0; pBmi->bmiHeader.biClrImportant = 0; //-- Fill in the file header --/ bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) + colorSize; bfh.bfReserved1 = 0; bfh.bfReserved2 = 0; bfh.bfSize = bfh.bfOffBits + dataSize; bfh.bfType = MAKEWORD('B','M'); //-- Create the memory Bitmap --/ hMem = GlobalAlloc(GMEM_FIXED, dataSize); if (hMem != NULL) { pBuf = (PBYTE)GlobalLock(hMem); //-- Get the bitmap bits in device independent format --/ hdc = GetDC(NULL); if (GetDIBits(hdc, hBitmap, 0, bm.bmHeight, pBuf, pBmi, DIB_RGB_COLORS) != 0) { ReleaseDC(NULL, hdc); //-- Write to file --/ WriteFile(hFile, &bfh, sizeof(bfh), &nWritten, NULL); WriteFile(hFile, pBmi, sizeof(BITMAPINFO) + colorSize, &nWritten, NULL); WriteFile(hFile, pBuf, dataSize, &nWritten, NULL); } //-- Clean up --/ GlobalUnlock(hMem); GlobalFree(hMem); } free(pBmi); } CloseHandle(hFile); return 0; }
-
@John
ES FUNKTIONIERT!!
ICH DANKE DIR!!!!!
-
Original erstellt von <rr>:
man tut das bild direkt speichern.Hast schon recht. Ich wollte ihm nur zeigen, wie er die Funktion aus den FAQ anwenden kann. Klar ist Johns Methode besser.
@<STRG+C>: Hast du auch darauf geachtet, dass du das HBITMAP, welches du von GetClipboardData() bekommst, auch per CopyImage() kopierst in ein neues HBITMAP?
-
@WebFritzi
wie meinst du das?
nicht gleich ein HBITMAP-Handle drauf setzten sondern mit CopyImage ein neues Handle erstellen?if( OpenClipboard(NULL) ) { if( IsClipboardFormatAvailable(CF_BITMAP) ) { HBITMAP hBitmap = (HBITMAP)CopyImage((HBITMAP)GetClipboardData(CF_BITMAP), IMAGE_BITMAP, NULL, NULL, NULL); StoreBitmapInFiles(sBmp, hBitmap); CloseHandle(hBitmap); } CloseClipboard(); }
-
Naja... fast.
if( OpenClipboard(NULL) ) { if( IsClipboardFormatAvailable(CF_BITMAP) ) { HBITMAP handle = GetClipboardData(CF_BITMAP); HBITMAP hBmp = CopyImage(handle, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG); StoreBitmapInFiles(sBmp, hBmp); DeleteObject(hBmp); } CloseClipboard(); }
Du darfst das Handle, welches du von GetClipboardData() bekommst nicht wieder mit CloseHandle() schließen. Dazu die SDK-Hilfe:
The application must not free the handle nor leave it locked.
[ Dieser Beitrag wurde am 10.04.2003 um 20:26 Uhr von WebFritzi editiert. ]