Bitmap laden => speichern
-
Hallo, ich möchte eine Bitmap laden verändern und speichern.
Nach langem tüfteln habe ich es geschaft die Bitmap zu laden und an die einzelenen Farbwerte zu kommen:
//Teste , ob die zu öffnende Datei exsistiert fstream file; file.open(filename, ios::in); if (!file) { file.close(); return false; } //Lade das HBITMAP HBITMAP phBitmap; phBitmap = (HBITMAP)LoadImage( NULL,filename, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE ); BITMAP bm; GetObject(phBitmap, sizeof(BITMAP), &bm ); groesse =(bm.bmBitsPixel/8) * bm.bmWidth * bm.bmHeight; BYTE *pBuffer = new BYTE[groesse]; GetBitmapBits(phBitmap,groesse, pBuffer) ;Jetzt wollte ich zum Test einfach das Bild heller machen also
for (long x=0; x< bm.bmWidth * bmHeigh; x++) { if (pBuffer[x] <= 245) {pBuffer[x]=pBuffer[x]+10; }Ich habe mir auch schon im Archiv folgendes angesehen:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-39400.html
Da ich aber noch nicht so viel Ahnung habe komme ich damit nicht zurecht.Wie kann ich nun dieses Array von Farbinformationen wieder als BMP abspeichern?
-
Also, wie man eine Bitmap speichert kann ich dir nicht sagen.
Aber das mit der Datei existiert, macht man mmit [url="FileExists"]http://msdn2.microsoft.com/en-us/library/x23stk5t.aspx[/url]
mfg
-
Gut,hab ich jetrzt mit File exists und wie speicher ich die farbinformationen wieder als BMP ab?
-
-
Hallo, es funktioniert leider noch nicht ganz. Ich versuche jetzt das Bild erst einmal nur Pixel für Pixel zu kopieren ohne Manipulationen. Doch leider wird das
BMP was ich erhalte riesig (Einige Hundert MB) und ist nicht zu öffnen, da fehlerhaft.PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp) { BITMAP bmp; PBITMAPINFO pbmi; WORD cClrBits; // Retrieve the bitmap color format, width, and height. if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp)) {} // Convert the color format to a count of bits. cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); if (cClrBits == 1) cClrBits = 1; else if (cClrBits <= 4) cClrBits = 4; else if (cClrBits <= 8) cClrBits = 8; else if (cClrBits <= 16) cClrBits = 16; else if (cClrBits <= 24) cClrBits = 24; else cClrBits = 32; // Allocate memory for the BITMAPINFO structure. (This structure // contains a BITMAPINFOHEADER structure and an array of RGBQUAD // data structures.) if (cClrBits != 24) pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1<< cClrBits)); // There is no RGBQUAD array for the 24-bit-per-pixel format. else pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER)); // Initialize the fields in the BITMAPINFO structure. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = bmp.bmWidth; pbmi->bmiHeader.biHeight = bmp.bmHeight; pbmi->bmiHeader.biPlanes = bmp.bmPlanes; pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; if (cClrBits < 24) pbmi->bmiHeader.biClrUsed = (1<<cClrBits); // If the bitmap is not compressed, set the BI_RGB flag. pbmi->bmiHeader.biCompression = BI_RGB; // Compute the number of bytes in the array of color // indices and store the result in biSizeImage. // For Windows NT, the width must be DWORD aligned unless // the bitmap is RLE compressed. This example shows this. // For Windows 95/98/Me, the width must be WORD aligned unless the // bitmap is RLE compressed. pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8 * pbmi->bmiHeader.biHeight; // Set biClrImportant to 0, indicating that all of the // device colors are important. pbmi->bmiHeader.biClrImportant = 0; return pbmi; } void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC) { HANDLE hf; // file handle BITMAPFILEHEADER hdr; // bitmap file-header PBITMAPINFOHEADER pbih; // bitmap info-header LPBYTE lpBits; // memory pointer DWORD dwTotal; // total count of bytes DWORD cb; // incremental count of bytes BYTE *hp; // byte pointer DWORD dwTmp; pbih = (PBITMAPINFOHEADER) pbi; lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); if (!lpBits) {} // Retrieve the color table (RGBQUAD array) and the bits // (array of palette indices) from the DIB. if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, DIB_RGB_COLORS)) {} // Create the .BMP file. hf = CreateFile(pszFile, GENERIC_READ | GENERIC_WRITE, (DWORD) 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); if (hf == INVALID_HANDLE_VALUE) {} hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" // Compute the size of the entire file. hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof(RGBQUAD) + pbih->biSizeImage); hdr.bfReserved1 = 0; hdr.bfReserved2 = 0; // Compute the offset to the array of color indices. hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof (RGBQUAD); // Copy the BITMAPFILEHEADER into the .BMP file. if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwTmp, NULL)) { } // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) + pbih->biClrUsed * sizeof (RGBQUAD), (LPDWORD) &dwTmp, ( NULL))) {} // Copy the array of color indices into the .BMP file. dwTotal = cb = pbih->biSizeImage; hp = lpBits; if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) {} // Close the .BMP file. if (!CloseHandle(hf)) {} // Free memory. GlobalFree((HGLOBAL)lpBits); } HBITMAP ManipulateBitmap( LPCWSTR _file) { DWORD _width, _height; HBITMAP _bitmap, DestBitmap; HBITMAP newBitmap=NULL; if(!_file) return NULL; _bitmap= (HBITMAP)LoadImage(0,_file,IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE|LR_CREATEDIBSECTION); if(!_bitmap) return NULL; BITMAP bm; GetObject(_bitmap, sizeof(bm), &bm); _width=bm.bmWidth; _height=bm.bmHeight; DestBitmap=CreateBitmapIndirect(&bm); if(!_bitmap) return NULL; HDC SrcDC=CreateCompatibleDC(NULL);; SelectObject(SrcDC,_bitmap); HDC DestDC=CreateCompatibleDC(NULL);; SelectObject(DestDC,DestBitmap); //Einfach nur die Pixel Kopieren DWORD col1; for(DWORD y=0; y<_height; y++) { for(DWORD x=0; x<_width; x++) { col1=GetPixel(SrcDC,x,y); byte r,g,b; r=GetRValue(col1); g=GetGValue(col1); b=GetBValue(col1); SetPixel(DestDC,x,y,RGB(r,g,b)); } } DeleteDC(DestDC); DeleteDC(SrcDC); DeleteObject(_bitmap); return DestBitmap; }Ich rufe es folgendermaßen auf:
HBITMAP h=ManipulateBitmap(L"1.bmp");CreateBMPFile(g_window->hWnd,L"test.bmp",CreateBitmapInfoStruct(g_window->hWnd,h),h,g_window->hDC);
Weiß Jemand was schief läuft?
(Die Methoden CreateBMPFile(...) und CreateBitmapInfoStruct(...) habe ich von der Microsoft Seite übernommen.
-
Also ich habe den fehler eingegerenzt und er ist mit Sicherheit in ManipulateBitmap
Weiß Jemand was dort falsch ist?
-
Also, ich bin mir jetzt ziemlich sicher, das dies nicht funktioniert:
//Einfach nur die Pixel Kopieren DWORD col1; for(DWORD y=0; y<_height; y++) { for(DWORD x=0; x<_width; x++) { col1=GetPixel(SrcDC,x,y); byte r,g,b; r=GetRValue(col1); g=GetGValue(col1); b=GetBValue(col1); SetPixel(DestDC,x,y,RGB(r,g,b)); } }Weiß Jemand wo hier der Fehler ist?
-
Prüf den Rückgabewert von GetPixel doch mal auf CLR_INVALID und auch den Rückgabewert von SetPixel

-
Hallo, ich habe jetzt endgültig die Zeilen gefunden, die nicht funktionieren:
DestBitmap=CreateBitmapIndirect(&bm); if(!_bitmap) return NULL; HDC SrcDC=CreateCompatibleDC(NULL);; SelectObject(SrcDC,_bitmap); HDC DestDC=CreateCompatibleDC(NULL);; SelectObject(DestDC,DestBitmap);denn wenn ich
SetPixel(ScrDC,x,y,RGB(r,g,b));anstatt
SetPixel(DestDC,x,y,RGB(r,g,b));benutze geht es.
Warum funktioniert das kopieren der Bitmap so nicht?