CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Jun 2013
    Posts
    20

    Is it nessecary to display a array of bytes without converting to HBITMAP

    I followed a tutorial to load a bitmap from file and convert it to a array of bytes to access it directly. Now to display the bitmap on screen do I have to convert it to a HBITMAP or can I display it from the array of bytes?

    Also the program I am building is a calendar program and I need to know if I can manipulate the bitmaps pixels in the byte array (e.g change color and resize image)

    here is the code to load the bitmap

    HTML Code:
    BYTE* Sprite2::LoadBMP(int* width, int* height, long* size, LPCTSTR bmpfile )
    {
    	BITMAPFILEHEADER bmpheader;
    	BITMAPINFOHEADER bmpinfo;
    	DWORD bytesread;
    
    	HANDLE file = CreateFile(bmpfile,GENERIC_READ, FILE_SHARE_READ,
    		0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
    	if(0 == file)
    		return 0;
    
    	if(ReadFile ( file, &bmpheader, sizeof( BITMAPFILEHEADER),
    		&bytesread, 0 ) == false )
    	{
    		CloseHandle (file );
    		return 0;
    	}
    
    	if( ReadFile ( file, &bmpinfo, sizeof ( BITMAPINFOHEADER ),
    		&bytesread, 0 ) == false )
    	{
    		CloseHandle ( file );
    		return 0;
    	}
    
    	if( bmpheader.bfType != 'MB' )
    	{
    		CloseHandle( file );
    		return 0;
    	}
    
    	if( bmpinfo.biCompression != BI_RGB )
    	{
    		CloseHandle( file );
    		return 0;
    	}
    
    	if( bmpinfo.biBitCount != 24 )
    	{
    		CloseHandle( file );
    		return 0;
    	}
    
    	*width = bmpinfo.biWidth;
    	*height = abs (bmpinfo.biHeight);
    	*size = bmpheader.bfSize - bmpheader.bfOffBits;
    
    	BYTE* Buffer = new BYTE[ *size ];
    
    	SetFilePointer ( file, bmpheader.bfOffBits, 0, FILE_BEGIN );
    
    	if( ReadFile (file, Buffer, *size, &bytesread, 0 ) == false)
    	{
    		delete [] Buffer;
    		CloseHandle( file );
    		return 0;
    	}
    
    	CloseHandle( file );
    	return Buffer;
    
    }

  2. #2
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Is it nessecary to display a array of bytes without converting to HBITMAP

    Quote Originally Posted by william3711 View Post
    I followed a tutorial to load a bitmap from file and convert it to a array of bytes to access it directly. Now to display the bitmap on screen do I have to convert it to a HBITMAP or can I display it from the array of bytes?
    . . .
    here is the code to load the bitmap
    It's always important to give things their real names. Your code is not about loading bitmap. It just reads the bitmap attributes (width, height, size) and bits data out of the file on disk. And what you call convert to HBITMAP really is loading bitmap bits to GDI bitmap object and obtaining handle to it. The handle is going to be of HBITMAP type, and with this handle you're able to instruct Windows to display the bitmap. Please note, object handle is not the object itself. So you have no reasonable way to convert anything to handle, instead you manipulate with the target object via available APIs that accept handle of proper type.

    So ultimately, rephrasing your question, you have a bitmap attributes and bits (no matter, modified or not). Which way you could show the bitmap? You create a DIB section bitmap and load your bits to it. Or, which seems easier to me, you load your bitmap from file to a DIB section bitmap object and manipulate directly with its bits (which implies, you throw away your LoadBMP code and develop a new one). The choice is yours.
    Best regards,
    Igor

  3. #3
    Join Date
    Jun 2013
    Posts
    20

    Re: Is it nessecary to display a array of bytes without converting to HBITMAP

    Thanks for the answer I usually use this code

    #include"Sprite.h"
    #include<cassert>
    Sprite::Sprite(HINSTANCE hAppInst, int imageID, int maskID,
    const Vec2& pos, const Vec2& vel)
    {
    mhAppInst = hAppInst;

    mhImage = LoadBitmap(hAppInst, MAKEINTRESOURCE(imageID));
    mhMask = LoadBitmap(hAppInst, MAKEINTRESOURCE(maskID));

    GetObject(mhImage, sizeof(BITMAP),&mImageBM);
    GetObject(mhMask, sizeof(BITMAP), &mMaskBM);

    assert(mImageBM.bmWidth == mMaskBM.bmWidth);
    assert(mImageBM.bmHeight == mMaskBM.bmHeight);

    sourceXPos = 0;
    sourceYPos = 0;
    sourceWidth = mImageBM.bmWidth;
    sourceHeight = mImageBM.bmHeight;


    mPos = pos;
    mVel = vel;



    rect = Rect(mPos.x, mPos.y, sourceWidth, sourceHeight);
    }

    Sprite::~Sprite()
    {
    DeleteObject(mhImage);
    DeleteObject(mhMask);
    }

    int Sprite::width()
    {
    return mImageBM.bmWidth;
    }

    int Sprite::height()
    {
    return mImageBM.bmHeight;
    }

    void Sprite::Update(float dt)
    {

    }



    void Sprite:raw(HDC hBackBufferDC, HDC hSpriteDC)
    {

    int w = width();
    int h = height();

    int x = (int)mPos.x;
    int y = (int)mPos.y;

    int srcX = sourceXPos;
    int srcY = sourceYPos;

    HGDIOBJ oldObj = SelectObject(hSpriteDC, mhMask);

    BitBlt(hBackBufferDC, x, y, sourceWidth, sourceHeight, hSpriteDC, srcX, srcY, SRCAND);

    SelectObject(hSpriteDC, mhImage);

    BitBlt(hBackBufferDC, x, y, sourceWidth, sourceHeight, hSpriteDC, srcX, srcY, SRCPAINT);

    SelectObject(hSpriteDC, oldObj);

    }

    but I didn't know how to load bitmaps directly from file rather than with the resource editor and the tutorial was the only thing I could find for what it called loading and saving bitmaps and it said

    "Most of the time we want to work with the bitmap data directly and not just display it on a window dc, so the next thing i'll show you is how to load a bitmap."

    somehow I guess I misunderstood what it was saying but thanks for clarifying. Is there another way to load from file and not the resource editor. I want to make it so people can use there own pics in calendar.

  4. #4
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Is it nessecary to display a array of bytes without converting to HBITMAP

    LoadImage function is able to load bitmap from file when LR_LOADFROMFILE is specified. LR_CREATEDIBSECTION instructs to load it to DIB section where the bitmap bits become available for modification.
    Best regards,
    Igor

  5. #5
    Join Date
    Jun 2013
    Posts
    20

    Re: Is it nessecary to display a array of bytes without converting to HBITMAP

    Thanks again I am going to switch my code up and use the load image function. And I just read a little about DIB sections and that appears to be exactly what I need being you can access the pixel data directly via a pointer. I also read its faster than bitmaps.

  6. #6
    Join Date
    Jun 2013
    Posts
    20

    Re: Is it nessecary to display a array of bytes without converting to HBITMAP

    Just tested out loading a drawing a bitmap from file in winMain I

    #include<Windows.h>


    HINSTANCE hAppInst = 0;
    HWND hMainWnd = 0;
    HDC hSpriteDC = 0;
    HBITMAP hBitmap;



    const int gClientWidth = 1000;
    const int gClientHeight = 803;

    const POINT gClientCenter =
    {
    gClientWidth / 2,
    gClientHeight / 2

    };





    bool InitMainWindow();
    int run();

    LRESULT CALLBACK
    WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);




    int WINAPI
    WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR cmdLine, int showCmd)
    {
    hAppInst = hInstance;

    if(!InitMainWindow())
    {
    MessageBox(0, "Main Window Failed", "Error", MB_OK);
    return 0;
    }


    return run();
    }

    bool InitMainWindow()
    {
    WNDCLASS wc;

    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)::GetStockObject(NULL_BRUSH);
    wc.hCursor = ::LoadCursorA(0, IDC_ARROW);
    wc.hIcon = ::LoadIconA(0, IDI_APPLICATION);
    wc.hInstance = hAppInst;
    wc.lpfnWndProc = WndProc;
    wc.lpszClassName = "CellDamage";
    wc.lpszMenuName = 0;
    wc.style = CS_HREDRAW | CS_VREDRAW;

    RegisterClass(&wc);

    hMainWnd = CreateWindow("CellDamage","CellDamage", WS_OVERLAPPED | WS_SYSMENU, 0, 0, gClientWidth, gClientHeight, 0, 0, hAppInst, 0);

    if(hMainWnd == 0)
    {
    MessageBox(0, "Window Creation Failed", "Error", MB_OK);
    return 0;
    }

    ShowWindow(hMainWnd, SW_NORMAL);
    UpdateWindow(hMainWnd);



    return true;
    }

    int run()
    {
    MSG msg;
    ZeroMemory(&msg, sizeof(MSG));



    while(msg.message != WM_QUIT)
    {
    if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }

    else
    {




    BITMAP BMP;
    GetObject(hBitmap, sizeof(BMP), &BMP); // Here we get the BMP header info.

    HDC BMPDC = CreateCompatibleDC(0); // This will hold the BMP image itself.

    HDC hDC = GetDC(hMainWnd);
    SelectObject(BMPDC, hBitmap); // Put the image into the DC.

    BitBlt(hDC, 0, 0, BMP.bmWidth, BMP.bmHeight, BMPDC, 0, 0, SRCCOPY); // Finally, Draw it

    ReleaseDC(hMainWnd, hDC);
    DeleteDC(BMPDC);
    // Don't forget to clean up!







    }
    }
    return (int)msg.wParam;
    }



    LRESULT CALLBACK
    WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    switch(msg)
    {
    case WM_CREATE:

    hBitmap = (HBITMAP)LoadImage(hAppInst, "C:\\Users\\Billy\\Documents\\Calendarpic\\CalendarBaseAqua.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
    hSpriteDC = CreateCompatibleDC(0);


    return 0;

    case WM_RBUTTONDOWN:

    return 0;



    case WM_DESTROY:


    DeleteObject(hBitmap);

    DeleteDC(hSpriteDC);

    PostQuitMessage(0);
    return 0;
    }

    return DefWindowProc(hWnd, msg, wParam, lParam);
    }


    Now can modify the bitmap bits correct.

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Is it nessecary to display a array of bytes without converting to HBITMAP

    Before posting, please format your code with indents etc. Also please use code tags. Go Advanced, select code, click '#'.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured