Creating Hbitmap from Memory Buffer

Creating HBITMAP from memory buffer

Using GdiPlus I got something that works pretty well and doesn't involve pulling any teeth!

Gdiplus::Bitmap* pBitmap = NULL;
IStream* pStream = NULL;

HRESULT hResult = ::CreateStreamOnHGlobal( NULL, TRUE, &pStream );
if(hResult == S_OK && pStream)
{
hResult = pStream->Write(&bits[0], ULONG(bits.size()), NULL);
if(hResult == S_OK)
pBitmap = Gdiplus::Bitmap::FromStream(pStream);
pStream->Release();
}

Edit: Changed per Jegatheesh

Can't properly load bitmap from the memory

It might be helpful for others how may encounter this issue(black square which has dimensions of the image you are trying to load).

3-rd method works.

BITMAPFILEHEADER* pBmfh = (BITMAPFILEHEADER*)ibuf;
BITMAPINFOHEADER* pBmih = (BITMAPINFOHEADER*)(ibuf + sizeof(BITMAPFILEHEADER));
BITMAPINFO* pBmi = (BITMAPINFO*)pBmih;
void* pBMPdata = (void*)(ibuf + pBmfh->bfOffBits);
void* pToFill = 0;
hBitmap = CreateDIBSection(NULL, pBmi, DIB_RGB_COLORS, &pToFill, NULL, NULL);

memcpy(pToFill, pBMPdata, pBmfh->bfSize - pBmfh->bfOffBits); // this line should be added!!

My mistake was, that I was trying to pass pointer to pointer to the databits, instead of it
I should after invokage copy databits to the void (which is pToFill).**

Displaying all Bitmap Types from a Memory Buffer with MFC or Win32

Hans is correct to say that bi.bmiColors was not being treated correctly. Instead of handling the bi.bmiColors table directly, just point pBitmapInfo to the appropriate offset in BITMAPFILEHEADER and cast. This takes care of the color table automatically. And yes, pBitmapInfo and pBitmapInfoHeader do point to the same place; what they point to is casted differently in each case. Both of those pointers a required by the CreateDIBitmap() function.

pBitmapFileHeader = (LPBITMAPFILEHEADER)buf1;
pBitmapInfoHeader = (LPBITMAPINFOHEADER)(buf1+sizeof(BITMAPFILEHEADER));
pBitmapInfo = (LPBITMAPINFO)(buf1+sizeof(BITMAPFILEHEADER));
pPixels = (buf1+pBitmapFileHeader->bfOffBits);

Then in OnPaint() do:

g_hBmp = CreateDIBitmap(dcPaint, pBitmapInfoHeader, CBM_INIT, (VOID *) pPixels, pBitmapInfo, DIB_RGB_COLORS);

Create a Windows GDI Bitmap from memory

You'll have to use CreateDIBSection to make a new buffer, then copy your bits into it....like so:

std::ifstream is;
is.open("Image.bmp", std::ios::binary);
is.seekg (0, std::ios::end);
length = is.tellg();
is.seekg (0, std::ios::beg);
pBuffer = new char [length];
is.read (pBuffer,length);
is.close();

tagBITMAPFILEHEADER bfh = *(tagBITMAPFILEHEADER*)pBuffer;
tagBITMAPINFOHEADER bih = *(tagBITMAPINFOHEADER*)(pBuffer+sizeof(tagBITMAPFILEHEADER));
RGBQUAD rgb = *(RGBQUAD*)(pBuffer+sizeof(tagBITMAPFILEHEADER)+sizeof(tagBITMAPINFOHEADER));

BITMAPINFO bi;
bi.bmiColors[0] = rgb;
bi.bmiHeader = bih;

char* pPixels = (pBuffer+bfh.bfOffBits);

char* ppvBits;

hBitmap = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void**) &ppvBits, NULL, 0);
SetDIBits(NULL, hBitmap, 0, bih.biHeight, pPixels, &bi, DIB_RGB_COLORS);

GetObject(hBitmap, sizeof(BITMAP), &cBitmap);


Related Topics



Leave a reply



Submit