bitmap auf festplatte speichern



  • hi leute,

    kann mir vielleicht jemand sagen wie ich ein bitmap als bmp-datei auf festplatte speichern kann ?



  • bestimmt.

    aber kannst du auch mal die suchfunktion benutzen, oder in der faq blättern, oder bei codeguru / codeproject schauen?





  • zum 4. Mal in letzer Zeit:

    BOOL WriteBitmap( LPTSTR szFile, HBITMAP hbitmap, HDC memdc) 
    { 
          BITMAP  bmp; 
          if(GetObject(hbitmap, sizeof(BITMAP), &bmp)) 
          { 
            BITMAPINFOHEADER BmpInfoHdr; 
         BITMAPFILEHEADER BmpFileHdr; 
             BmpInfoHdr.biSize = sizeof(BITMAPINFOHEADER); 
            BmpInfoHdr.biWidth = bmp.bmWidth; 
        BmpInfoHdr.biHeight = bmp.bmHeight; 
            BmpInfoHdr.biPlanes = bmp.bmPlanes; 
        BmpInfoHdr.biBitCount = 24; 
            BmpInfoHdr.biCompression    = BI_RGB; 
             BmpInfoHdr.biSizeImage        = bmp.bmWidth*bmp.bmHeight*3; 
             BmpFileHdr.bfType        = 0x4d42; 
             BmpFileHdr.bfReserved1        = 0; 
             BmpFileHdr.bfReserved2        = 0; 
             BmpFileHdr.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof (BITMAPINFOHEADER); 
            BmpFileHdr.bfSize = BmpFileHdr.bfOffBits+BmpInfoHdr.biSizeImage; 
            bmp.bmBits = (void*)GlobalAlloc(GMEM_FIXED, BmpInfoHdr.biSizeImage); 
            if(GetDIBits(memdc, hbitmap, 0, BmpInfoHdr.biHeight, bmp.bmBits, (BITMAPINFO*)&BmpInfoHdr, DIB_RGB_COLORS) == BmpInfoHdr.biHeight) 
            { 
                HANDLE hFile = CreateFile(szFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL); 
                if(hFile != INVALID_HANDLE_VALUE)  { 
                DWORD dwTmp; 
                WriteFile(hFile, &BmpFileHdr, sizeof(BITMAPFILEHEADER), &dwTmp, NULL); 
                WriteFile(hFile, &BmpInfoHdr, sizeof(BITMAPINFOHEADER), &dwTmp, NULL); 
                WriteFile(hFile, bmp.bmBits,  BmpInfoHdr.biSizeImage,   &dwTmp, NULL); 
            } 
            CloseHandle(hFile); 
        } 
        GlobalFree(bmp.bmBits); 
        return TRUE; 
      } 
      return FALSE; 
    }
    

    😉 😉

    Grüße Rapha



  • [code]void CBMPDoc::OnSavebmp()
    {
    // TODO: Code für Befehlsbehandlungsroutine hier einfügen

    CRect rRect;
    CString sFilename;

    POSITION pos = GetFirstViewPosition();
    CBMPView *pView = (CBMPView*) GetNextView(pos);

    static char BASED_CODE szFilter[] = "Bitmap-Dateien (.bmp)|.bmp||";
    //dialogfeld öffnen erzeugen
    CFileDialog ldFile(false, ".bmp", m_sBitmap, OFN_HIDEREADONLY |
    OFN_OVERWRITEPROMPT, szFilter);

    //dialogfeld öffnen anzeigen
    if(ldFile.DoModal() == IDOK){
    //Gewählten dateinamen ermitteln
    sFilename = ldFile.GetPathName();
    }

    if(pView){

    CDC *pDC;
    pDC = pView->GetDC();//gerätekontext holen
    pView->GetClientRect(&rRect);//größe des fensters

    DC2Bitmap(*pDC, rRect.Width(), rRect.Height(),"c:\\tst.bmp");

    }
    }

    //erzeugt aus gerätekontext ein bitmap und speichert es auf festplatte (gefunden)
    int CBMPDoc::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;

    bi.bmiHeader=bmih;

    aBmp=CreateDIBSection(hdc,&bi,DIB_RGB_COLORS,(void**)&dibvalues,0,0);

    if(aBmp==NULL)
    {
    OutputDebugString("CreateDIBSection failed!\n");
    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)
    {
    OutputDebugString("CreateFile failed!\n");
    return 0;
    }

    bytes_write=sizeof(BITMAPFILEHEADER);

    if (!WriteFile(fileHandle,(void*)&bmfh,bytes_write,&bytes_written,NULL))
    {
    OutputDebugString("WriteFile failed!\n");
    return 0;
    }

    bytes_write=sizeof(BITMAPINFOHEADER);

    if(!WriteFile(fileHandle,(void*)&bmih,bytes_write,&bytes_written,NULL))
    {
    OutputDebugString("WriteFile failed!\n");
    return 0;
    }

    bytes_write=bmih.biSizeImage;

    if(!WriteFile(fileHandle,(void*)dibvalues,
    bytes_write,&bytes_written,NULL))
    {
    OutputDebugString("WriteFile failed!\n");
    return 0;
    }

    CloseHandle(fileHandle);

    DeleteObject(SelectObject(hdc2,OldObj));
    DeleteDC(hdc2);

    return 1;
    }



  • hi leute danke für eure hilfe ich hab was gefunden.
    den code von dir rapha hab ich ausprobiert hat aber leider nicht geklappt.
    ich hab folgendes eingegeben
    CDC *pDC;
    pDC = pView->GetDC();//gerätekontext holen
    pView->GetClientRect(&rRect);//größe des fensters
    CBitmap bmp;
    bmp.CreateCompatibleBitmap(pDC,rRect.Width(), rRect.Height());
    pDC->SelectObject(bmp);
    WriteBitmap("c:\\tst.bmp",(HBITMAP) bmp,*pDC);
    das hat dazu geführt das mein programm abstürz. hab auch keine ahnung warum?

    ich hab hier einen code der funktioniert.
    ich hab nun aber das problem, dass wenn ich OnSavebmp() zum 2. mal aufrufe,
    dann speichert er auch das dialogfeld ldFile als bmp. woran kann das liegen ??



  • Hi,
    du musst ein MemoryDC erstellen und den Inhalt von pDC da hineinblitten.
    Ist ganz einfach

    Ich hab dir ne kleine Beispielanwendung (5 Min) geschrieben:
    Einfach die BitmapTest runterladen: http://mitglied.lycos.de/rame03/files.htm

    Grüße Rapha



  • ich hab folgendes eingegeben, das führt aber auch zum absturz.
    speichert das bild zwar, aber auch das dialogfeld von ldFile, obwohl ich
    WriteBitmap später aufrufe. was kann man denn machen damit er das dialogfeld
    nicht mehr anzeigt ?

    [cpp]POSITION pos = GetFirstViewPosition();
    CBMPView *pView = (CBMPView*) GetNextView(pos);
    static char BASED_CODE szFilter[] = "Bitmap-Dateien (.bmp)|.bmp||";

    CFileDialog ldFile(false, ".bmp", m_sBitmap, OFN_HIDEREADONLY |
    OFN_OVERWRITEPROMPT, szFilter);

    if(ldFile.DoModal() == IDOK){
    //Gewählten dateinamen ermitteln
    sFilename = ldFile.GetPathName();
    }
    if(pView){
    CDC *pDC,DC;
    CBitmap Bitmap;

    pDC = pView->GetDC();//gerätekontext holen
    CRect rRect;
    pView->GetClientRect(&rRect);//größe des fensters
    DC.CreateCompatibleDC(pDC);
    if(!Bitmap.CreateCompatibleBitmap(pDC, rRect.right - rRect.left, rRect.bottom - rRect.top))
    {
    DC.DeleteDC();
    AfxMessageBox("Bitmap konnte nicht erstellt werden");
    return;
    }

    DC.SelectObject(&Bitmap);
    DC.BitBlt(0, 0, rRect.right - rRect.left, rRect.bottom - rRect.top, pDC, 0, 0, SRCCOPY);

    // Bitmap schreiben:
    WriteBitmap("C:\\Test.bmp", (HBITMAP) Bitmap, (HDC) DC);

    // Und noch aufräumen
    Bitmap.DeleteObject();
    DC.DeleteDC();
    pDC = NULL;



  • Hm, an dem Code scheint alles in Ordnung zu sein (achja, du musst dein pDC noch richtig löschen: pView->ReleaseDC(pDC) und dann pDC = NULL;).

    Gib mal etwas mehr Code.
    Lass die Anwendung im Debug Modus laufen - gibt es irgendwelche Fehlermeldungen?
    Du sagst, dass deine Anwendung abstürzt, wie genau macht sie das?

    Wenn das mit dem Dialogfeld nicht geht (müsste eigendlich schon), dann könntest du einen Timer einbauen oder IdFile.ShowWindow(SW_HIDE); versuchen

    Grüße Rapha



  • er geht bis zu GlobalFree(bmp.bmBits); von WriteBitmap und gibt anschließend folgende meldung aus

    "Nicht abgefangene Ausnahme in SWM.exe (KERNEL32.DLL): 0xC0000005: Access Violation."



  • Hm, die Funktion ist vollkommen in Ordung 😕

    Gib mal ein paar Informationen mehr an.
    Dein OS, die Version von MSVC++, Version des Service Packs, usw.

    Hast du dir mein Beispielprojekt angeschaut?
    Wenn du dich Schritt für Schritt daran entlanghangelst, müsste es eingendlich gehen.

    Grüße Rapha


Anmelden zum Antworten