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?





  • Wie siehts mit GetDIBits() aus?


Anmelden zum Antworten