Problem mit Bitmap als DIB laden und anzeigen lassen
-
Ich möchte eine Bitmap (24- und 32 Bit Unterstützung) als DIB in den Speicher laden und im Fenster in einer Picturebox anzeigen lassen. Warum funktioniert mein Code nicht, bzw. was mache ich falsch?
// Win32Project_LoadBmp_IntoDIB.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "Win32Project_LoadBmp_IntoDIB.h" #define MAX_LOADSTRING 100 // Global Variables: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name // Forward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: Place code here. MSG msg; HACCEL hAccelTable; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_WIN32PROJECT_LOADBMP_INTODIB, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32PROJECT_LOADBMP_INTODIB)); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // FUNCTION: MyRegisterClass() // // PURPOSE: Registers the window class. // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT_LOADBMP_INTODIB)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WIN32PROJECT_LOADBMP_INTODIB); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } // // FUNCTION: InitInstance(HINSTANCE, int) // // PURPOSE: Saves instance handle and creates main window // // COMMENTS: // // In this function, we save the instance handle in a global variable and // create and display the main program window. // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } /******************************************************************* BYTE* LoadBMP ( int* width, int* height, long* size LPCTSTR bmpfile ) The function loads a 24 bit bitmap from bmpfile, stores it's width and height in the supplied variables and the whole size of the data (padded) in <size> and returns a buffer of the image data On error the return value is NULL. NOTE: make sure you [] delete the returned array at end of program!!! *******************************************************************/ BYTE* Buffer; BYTE* LoadBMP(int* width, int* height, long* size, LPCTSTR bmpfile) { // declare bitmap structures BITMAPFILEHEADER bmpheader; BITMAPINFOHEADER bmpinfo; // value to be used in ReadFile funcs DWORD bytesread; // open file to read from HANDLE file = CreateFile(bmpfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (NULL == file) return NULL; // coudn't open file // read file header if (ReadFile(file, &bmpheader, sizeof(BITMAPFILEHEADER), &bytesread, NULL) == false) { CloseHandle(file); return NULL; } //read bitmap info if (ReadFile(file, &bmpinfo, sizeof(BITMAPINFOHEADER), &bytesread, NULL) == false) { CloseHandle(file); return NULL; } // check if file is actually a bmp if (bmpheader.bfType != 'MB') { CloseHandle(file); return NULL; } // get image measurements *width = bmpinfo.biWidth; *height = abs(bmpinfo.biHeight); // check if bmp is uncompressed if (bmpinfo.biCompression != BI_RGB) { CloseHandle(file); return NULL; } // check if we have 24 bit bmp if (bmpinfo.biBitCount != 24) { CloseHandle(file); return NULL; } // create buffer to hold the data *size = bmpheader.bfSize - bmpheader.bfOffBits; Buffer = new BYTE[*size]; // move file pointer to start of bitmap data SetFilePointer(file, bmpheader.bfOffBits, NULL, FILE_BEGIN); // read bmp data if (ReadFile(file, Buffer, *size, &bytesread, NULL) == false) { delete[] Buffer; CloseHandle(file); return NULL; } // everything successful here: close file and return buffer CloseHandle(file); return Buffer; } BITMAPINFO bmi = { { sizeof(BITMAPINFOHEADER), 512, 512, 0, 24, BI_RGB, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; // // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) // // PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; static int x, y; long s; BYTE* a; switch (message) { case WM_CREATE: a = LoadBMP(&x, &y, &s, L"d:/RotoZoom3.bmp"); break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_\1: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: Add any drawing code here... StretchDIBits(hdc, 0, 0, 512, 512, 0, 0, 512, 512, Buffer, &bmi, DIB_RGB_COLORS, SRCCOPY); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // Message handler for about box. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
-
BMP Laden:
#include <windows.h> #include "resource.h" LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName [] = TEXT ("Bitmaps laden") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { // UNICODE-Compilierung ist die einzige realistische Fehlermöglichkeit MessageBox (NULL, TEXT ("Programm arbeitet mit Unicode und setzt Windows NT voraus!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, TEXT ("Bitmaps laden"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HBITMAP hBitmap ; static int cxClient, cyClient, cxSource, cySource ; BITMAP bitmap ; HDC hdc, hdcMem ; HINSTANCE hInstance ; int x, y ; PAINTSTRUCT ps ; switch (message) { case WM_CREATE: hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; hBitmap = LoadBitmap (hInstance, MAKEINTRESOURCE(IDB_BITMAP)) ; GetObject (hBitmap, sizeof (BITMAP), &bitmap) ; cxSource = bitmap.bmWidth ; cySource = bitmap.bmHeight ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; hdcMem = CreateCompatibleDC (hdc) ; SelectObject (hdcMem, hBitmap) ; for (y = 0 ; y < cyClient ; y += cySource) for (x = 0 ; x < cxClient ; x += cxSource) { BitBlt (hdc, x, y, cxSource, cySource, hdcMem, 0, 0, SRCCOPY) ; } DeleteDC (hdcMem) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: DeleteObject (hBitmap) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
Ressourcen:
#ifndef IDC_STATIC #define IDC_STATIC (-1) #endif #define IDR_MENU 100 #define IDM_DATEI_OEFFNEN 40000 #define IDM_DATEI_SPEICHERN 40001 #define IDM_DATEI_DRUCKEN 40002 #define IDM_BEENDEN 40003 #define IDM_AUSSCHNEIDEN 40004 #define IDM_KOPIEREN 40005 #define IDM_LOESCHEN 40006 #define IDM_ORIGINALE_GROESE 40007 #define IDM_ZENTRIERT 40008 #define IDM_FENSTER_GROESE_SKALIEREN 40009 #define IDM_ISOTROPHISCH_SKALIEREN 40010 #define IDR_ACCELERATOR 101 #define ID_DATEI_OEFFNEN 40000 #define ID_SPEICHERN 40001 #define ID_DRUCKEN 40002 #define ID_AUSSCHNEIDEN 40004 #define ID_KOPIEREN 40005 #define ID_ENTFERNEN 40006
-
@Mr C:
Vielen Dank für das Beispiel!
Ich habe lediglich LoadBitmap wie folgt geändert, da ich keine Resource benutze:hBitmap = (HBITMAP)LoadImage(NULL, L"d:\\Test.bmp", 0, 256, 256, 0x00008010);
In Deiner geposteten Resource sehe ich, dass Du anscheinend ein Beispiel mit einigen nützlichen Funktionen hast. Wäre es möglich, dieses komplette Beispiel mit allen Funktionen als ZIP oder per d/l-Link / URL zu erhalten?
Schonmal vielen Dank im voraus!
PS:
Wenn ich das richtig sehe, wird zwar eine Bitmap geladen und auch erfoglreich angezeigt. Wie kann ich jedoch die Bitmap direkt als DIB in den Speicher lesen (um hier später die Grafik zu manipulieren) und auf dem Fenster ausgeben?Die Grafik als DIB in den Speicher zu laden und anzuzeigen ist mir leider noch nicht gelungen.
-
Ich werder mich mal umschauen nach kostenlosen hosting, dann lade ich kompletten projekt hoch. Hoffe du wirst nicht alles gleich und sofort brauchen. ))
-
Warum überhaupt als DIB?
Soll die Bitmap noch vom Programm manipuliert werden oder nur angezeigt werden?"32 Bit Unterstützung"
...mit Alpha-Channel oder mit ungenutztem 4. Byte?
-
va!n hier:
http://workupload.com/file/4mgSsx3y
-
Wie siehts mit GetDIBits() aus?