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. ]


Anmelden zum Antworten