HWNd HDC bei Konsolenprogramm?
-
Hallo, ich möchte ein BMP berarbeiten und habe Code, der in einem Programm mit richtigem Fenster funktioniert.
Da ich die *.bmp nur lade, Daten manipulieren und wieder speichern möchte und es auch nicht anzeigen möchte, wollte ich es in einer Konsolenanwendung schreiben.
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; //Speicher pointer DWORD dwTotal; //totale Anzahl von bytes DWORD cb; //Zusätzliche Anzahl von Bytes BYTE *hp; //Byte pointer DWORD dwTmp; pbih = (PBITMAPINFOHEADER) pbi; lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); if (!lpBits) {} //// Hier fehlt noch eine Fehlermeldung /Fehlerbehandlung // //Holen der color table (RGBQUAD Array) und der Bits //(array von palette indices) von der "DIB". if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, DIB_RGB_COLORS)) {} //// Hier fehlt noch eine Fehlermeldung /Fehlerbehandlung // //Erzeuge die .BMP Datei. hf = CreateFile(pszFile, GENERIC_READ | GENERIC_WRITE, (DWORD) 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); if (hf == INVALID_HANDLE_VALUE) {} //// Hier fehlt noch eine Fehlermeldung /Fehlerbehandlung // hdr.bfType = 0x4d42; //0x42 = "B" 0x4d = "M" //berechne die Größe von der gesamten Datei. hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof(RGBQUAD) + pbih->biSizeImage); hdr.bfReserved1 = 0; hdr.bfReserved2 = 0; // Berechne den Offset des Arrays von Farb indices. hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof (RGBQUAD); //Kopiere die BITMAPFILEHEADER in die .BMP Datei. if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwTmp, NULL)) {} //// Hier fehlt noch eine Fehlermeldung /Fehlerbehandlung // //Kopiere die BITMAPINFOHEADER und RGBQUAD Arrays in die datei. if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) + pbih->biClrUsed * sizeof (RGBQUAD), (LPDWORD) &dwTmp, ( NULL))) {} //// Hier fehlt noch eine Fehlermeldung /Fehlerbehandlung // dwTotal = cb = pbih->biSizeImage; //kopiere das Array der color indices in die .BMP Datei. hp = lpBits; if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) {} //// Hier fehlt noch eine Fehlermeldung /Fehlerbehandlung // if (!CloseHandle(hf)) //Schließe die .BMP Datei. {} //// Hier fehlt noch eine Fehlermeldung /Fehlerbehandlung // GlobalFree((HGLOBAL)lpBits); //gib den Speicher frei. }Nun braucht aber die Methode (oben zu sehen) HWND und HDC.
Wie bekomme ich diese in einem Konsolemprogramm?
-
hwnd wird überhaupt nicht verwendet?
Für hdc kannste vermutlich das Screen-DC nehmen, welches du über GetDC(NULL) bekommst.
-
GetConsoleWindow() --> HWND (To compile an application that uses this function, define _WIN32_WINNT as 0x0500 or later.)
GetDC() --> HDC
-
Danke, es funktioniert jetzt.
Das Auslesen der Bilddaten und das Speichern der Datei scheinen mir in meiner Version doch extrem umständlich. Ich benutze folgende 3 Methoden aus meiner "Bilder" Klasse. (Ich habe mir die Methoden größtenteils aus der MSDN zusammengesucht)
Gibt es eine einfachere Möglichkeit als diese:
PBITMAPINFO Bilder::CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp) { BITMAP bmp; PBITMAPINFO pbmi; WORD cClrBits; //Hole das Bitmap color (farb) format, Breite, und höhe. if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp)) {} // Convertiere das color (farb) Format zu einer Anzahl von 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; //Belege Speicher für die BITMAPINFO Structur. (Diese Struktur //enthält eine BITMAPINFOHEADER Struktur und ein Array von RGB QUAD //Daten Structuren.) if (cClrBits != 24) pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1<< cClrBits)); // Es ist kein RGBQUAD Array für das 24-bit-per-pixel Format vorhanden else pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER)); // Initialisiere die Felder der BITMAPINFO Struktur. 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); //Wenn die Bitmap nicht komprimiert ist, setze das BI_RGB flag. pbmi->bmiHeader.biCompression = BI_RGB; //Berechne die Anzahl von Bytes in dem Color indices Array //und speichere das Ergebnis in biSizeImage. pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8 * pbmi->bmiHeader.biHeight; // Sete biClrImportant auf 0, um anzuzeigen, dass alle device farben wichtig sind pbmi->bmiHeader.biClrImportant = 0; return pbmi; } void Bilder::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; //Speicher pointer DWORD dwTotal; //totale Anzahl von bytes DWORD cb; //Zusätzliche Anzahl von Bytes BYTE *hp; //Byte pointer DWORD dwTmp; pbih = (PBITMAPINFOHEADER) pbi; lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); if (!lpBits) {} //// Hier fehlt noch eine Fehlermeldung /Fehlerbehandlung // //Holen der color table (RGBQUAD Array) und der Bits //(array von palette indices) von der "DIB". if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, DIB_RGB_COLORS)) {} //// Hier fehlt noch eine Fehlermeldung /Fehlerbehandlung // //Erzeuge die .BMP Datei. hf = CreateFile(pszFile, GENERIC_READ | GENERIC_WRITE, (DWORD) 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); if (hf == INVALID_HANDLE_VALUE) {} //// Hier fehlt noch eine Fehlermeldung /Fehlerbehandlung // hdr.bfType = 0x4d42; //0x42 = "B" 0x4d = "M" //berechne die Größe von der gesamten Datei. hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof(RGBQUAD) + pbih->biSizeImage); hdr.bfReserved1 = 0; hdr.bfReserved2 = 0; // Berechne den Offset des Arrays von Farb indices. hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof (RGBQUAD); //Kopiere die BITMAPFILEHEADER in die .BMP Datei. if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwTmp, NULL)) {} //// Hier fehlt noch eine Fehlermeldung /Fehlerbehandlung // //Kopiere die BITMAPINFOHEADER und RGBQUAD Arrays in die datei. if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) + pbih->biClrUsed * sizeof (RGBQUAD), (LPDWORD) &dwTmp, ( NULL))) {} //// Hier fehlt noch eine Fehlermeldung /Fehlerbehandlung // dwTotal = cb = pbih->biSizeImage; //kopiere das Array der color indices in die .BMP Datei. hp = lpBits; if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) {} //// Hier fehlt noch eine Fehlermeldung /Fehlerbehandlung // if (!CloseHandle(hf)) //Schließe die .BMP Datei. {} //// Hier fehlt noch eine Fehlermeldung /Fehlerbehandlung // GlobalFree((HGLOBAL)lpBits); //gib den Speicher frei. } HBITMAP Bilder::erzeuge_Manipuliertes_Bild( LPCWSTR file) { int width, height; //Variablen HBITMAP bitmap; HBITMAP newBitmap=NULL; if(!file) return NULL; //Wenn der angegebene Pfad nicht existiert, liefere NULL als HBITMAP zurück bitmap= (HBITMAP)LoadImage(0,file,IMAGE_BITMAP, 0, 0, //Lade das Bitmap in HBITMAP LR_DEFAULTSIZE|LR_LOADFROMFILE|LR_CREATEDIBSECTION); BITMAP bm; GetObject(bitmap, sizeof(BITMAP), &bm); //Kopiert das BITMAP aus dem HBITMAP width=bm.bmWidth; //Breite und hoehe auslesen height=bm.bmHeight; HDC SrcDC=CreateCompatibleDC(NULL); //Passenden HDC erzeugen SelectObject(SrcDC,bitmap); //OBjekt selektieren DWORD col1; for(int y=0; y<height; y++) //Durchlaufe alle Pixel { for(int x=0; x<width; x++) { col1=GetPixel(SrcDC,x,y); //Pixelfarben auslesen byte r,g,b; r=GetRValue(col1); g=GetGValue(col1); b=GetBValue(col1); int gesamt = r+g+b; //Wenn die Summe der Farben eines Pixels kleiner 72 ist if(gesamt<72) { SetPixel(SrcDC,x,y,RGB(0,255,0)); //setzte ein braunes Pixel } else { SetPixel(SrcDC,x,y,RGB(139,69,19)); //sonst ein rotes } } } DeleteDC(SrcDC); //HDC freigeben return bitmap; //HBITMAP zurückgeben }Ich rufe dies in der main Methode folgendermaßen auf:
int main() { HWND hWnd=GetConsoleWindow(); HDC hDC=GetDC(NULL); Bilder b = Bilder(); HBITMAP h= b.erzeuge_Manipuliertes_Bild(L"1.bmp"); b.CreateBMPFile(hWnd,L"2.bmp",b.CreateBitmapInfoStruct(hWnd,h),h,hDC); return 1; }