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?
-
Vor diesem Problem stand ich auch schonmal:
http://www.smalleranimals.com/isource/isourcesample.htm#BMP24
Damit hab ichs geschafft
Wenn nicht:
http://www.codeguru.com/bitmap/
http://www.nikis.de/181/vcnet.htm
http://people.freenet.de/cpp-programming.de.vu/quellcodes/code17.htmlSo das sollte reichen

greetz BigMama
-
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ügenCRect 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 fenstersDC2Bitmap(*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 einfachIch hab dir ne kleine Beispielanwendung (5 Min) geschrieben:
Einfach die BitmapTest runterladen: http://mitglied.lycos.de/rame03/files.htmGrüß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