Raw RGB image in memory - how to create a bitmap and palette I can use?

This is a discussion on Raw RGB image in memory - how to create a bitmap and palette I can use? within the Windows Programming forums, part of the Platform Specific Boards category; I suspect this is a trivial problem to solve but it's driving me nuts. I have functioning code that uses ...

  1. #1
    Registered User
    Join Date
    Jan 2013
    Posts
    10

    Raw RGB image in memory - how to create a bitmap and palette I can use?

    I suspect this is a trivial problem to solve but it's driving me nuts.


    I have functioning code that uses LoadBitmapFromBMPFile() which I lifted from Microsoft's web site to load a bitmap and display it so:

    Code:
    HBITMAP hOldBitmap, hBitmap;
    HPALETTE hOldPalette, hPalette;
    HDC hDC, hMemDC;
    BITMAP bm;
    
    [...]
    
    LoadBitmapFromBMPFile( L"somefile.bmp", &hBitmap, &hPalette );
    
    GetObject( hBitmap, sizeof(BITMAP), &bm );
    hMemDC = CreateCompatibleDC( hDC );
    hOldBitmap = (HBITMAP)SelectObject( hMemDC, hBitmap );
    hOldPalette = SelectPalette( hDC, hPalette, FALSE );
    RealizePalette( hDC );
    
    BitBlt( hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY );
    No problem.


    At a later point, I have a raw image in memory. RGB format, 8 bits per pixel. I want to BitBlt() this onto the display, same as above.

    I have functioning code that takes that image in memory, writes it to a file in BMP format, and then calls LoadBitmapFromBMPFile() as above ... but this is silly. I ought to be able to skip the file writing and reading.

    LoadBitmapFromBMPFile() starts off so:

    Code:
    BOOL LoadBitmapFromBMPFile( LPTSTR szFileName, HBITMAP *phBitmap,
       HPALETTE *phPalette )
       {
    
       BITMAP  bm;
    
       *phBitmap = NULL;
       *phPalette = NULL;
    
       // Use LoadImage() to get the image loaded into a DIBSection
       *phBitmap = (HBITMAP)LoadImage( NULL, szFileName, IMAGE_BITMAP, 0, 0,
                   LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
    Surely there's some analogue to LoadImage() that, instead of taking a filename as a parameter, can accept a pointer to the already-in-memory RGB image data?

    If there is, I haven't found it.



    Google has suggested I use CreateDIBSection(). This represents my non-successful attempt:

    Code:
    unsigned char *display_image_data;  // image data in 8 bpp RGB format
    
    [...]
    
    BITMAPINFO pbmi;
    
    pbmi.bmiheader.biSize = sizeof(BITMAPINFO);
    pbmi.bmiheader.biWidth = DISPLAY_X;  // img width in pixels
    pbmi.bmiheader.biHeight = DISPLAY_Y;  // img height in pixels
    pbmi.bmiheader.biPlanes = 1;
    pbmi.bmiheader.biBitCount = 24;  // also tried 8 here
    pbmi.bmiheader.biCompression = BI_RGB;
    pbmi.bmiheader.biSizeImage = 0;  // docs say 0 if BI_RGB is used
    pbmi.bmiheader.biXPelPerMeter = 0;  // no idea what to do with this
    pbmi.bmiheader.biYPelPerMeter = 0;  // or this
    pbmi.bmiheader.biClrUsed = 0;
    pbmi.bmiheader.biClrImportant = 0;
    // pbmi.bmiColors    shouldn't need for RGB
    
    hBitmap = CreateDIBSection( hDC, &pbmi, DIB_RGB_COLORS, (void **)display_image_data, NULL, 0 );
    
    GetObject( hBitmap, sizeof(BITMAP), &bm );
    hMemDC = CreateCompatibleDC( hDC );
    hOldBitmap = (HBITMAP)SelectObject( hMemDC, hBitmap );
    hOldPalette = SelectPalette( hDC, hPalette, FALSE );
    RealizePalette( hDC );
    
    BitBlt( hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY );
    And what I get is a big black rectangle painted to the screen.

    I would appreciate some tips here ... thank you.
    Last edited by 168gr; 04-09-2013 at 06:27 AM.

  2. #2
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,859
    pbmi.bmiheader.biSize = sizeof(BITMAPINFO);

    shouldn't this be
    pbmi.bmiheader.biSize = sizeof(BITMAPINFOHEADER);
    displaying bitmap

    Do set the struct to zero (ZeroMemory(&pbmi, sizeof BITMAPINFO) so any members you do not fill will not hold rubbish?

    Have you tried SetDiBits() ?
    Dynamic Bitmap Display

    Does CreateDIBSection() return an error?
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  3. #3
    Registered User
    Join Date
    Jan 2013
    Posts
    10
    After much wailing and gnashing of teeth, I got it to work. Not sure if this is the "correct" way to do it, but it does work. I used the CreateDIBitmap() function instead.
    Code:
       BITMAPINFOHEADER BitmapInfoHeader;    BitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);   BitmapInfoHeader.biWidth = DISPLAY_X;   BitmapInfoHeader.biHeight = -DISPLAY_Y;   BitmapInfoHeader.biPlanes = 1;   BitmapInfoHeader.biBitCount = 24;   BitmapInfoHeader.biCompression = BI_RGB;   BitmapInfoHeader.biSizeImage = 0;   BitmapInfoHeader.biXPelsPerMeter = 0;   BitmapInfoHeader.biYPelsPerMeter = 0;   BitmapInfoHeader.biClrUsed = 0;   BitmapInfoHeader.biClrImportant = 0;     *phBitmap = CreateDIBitmap( g_hDC, &BitmapInfoHeader, CBM_INIT, (LPVOID *)display_image_data, (LPBITMAPINFO)&BitmapInfoHeader, DIB_RGB_COLORS );
    I had to flip the sign on the .biHeight member to tell it I wanted 0,0 at the top left rather than the bottom left. And another thing that tripped me up is that Windows wants the data chunk in BGR order, not RGB ... took a few minutes to figure out why the red & blue were flipped on the image. Argh. Why does Microsoft want BGR ordered data?
    Code:
     for( k = 0; k < display_image_length/3; k ++ ) {   temp = display_image_data[k*3];   display_image_data[k*3] = display_image_data[k*3+2];   display_image_data[k*3+2] = temp; }

  4. #4
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,859
    From memory, is over 10 years since I did BMP capture for a RAT app...

    Only 24 bit images require the RGB reversed, based on the original OS/R implementation.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bitmap Image In C
    By snayyer in forum C Programming
    Replies: 9
    Last Post: 06-20-2011, 11:16 AM
  2. Create 24 bits bitmap in memory
    By pronecracker in forum Windows Programming
    Replies: 5
    Last Post: 05-05-2007, 11:51 AM
  3. palette from bitmap
    By Laserve in forum Windows Programming
    Replies: 8
    Last Post: 07-20-2006, 12:49 AM
  4. how to convert a bitmap image to a jpg image file using C++?
    By nomer in forum Windows Programming
    Replies: 4
    Last Post: 06-04-2006, 08:40 PM
  5. bitmap.palette help
    By Rune Hunter in forum C# Programming
    Replies: 2
    Last Post: 06-03-2005, 04:06 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21