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
How to Make My Split Work Only on One Real Line and Be Capable to Skip Quoted Parts of String
How to Get the Path of a Windows "Special Folder" for a Specific User
How to Check That an Element Is in a Std::Set
Generating a Normal Map from a Height Map
Can the C Preprocessor Be Used to Tell If a File Exists
Why Doesn't Emplace_Back() Use Uniform Initialization
How Is Vector Implemented in C++
C++ Virtual Table Layout of Mi(Multiple Inheritance)
Is It Safe to Realloc Memory Allocated with New
Get Current Time in Milliseconds Using C++ and Boost
C++ Equivalent of Java's Tostring
Why Should I Ever Use Inline Code
Why Is the Volatile Qualifier Used Through Out Std::Atomic
Serializing and Deserializing JSON with Boost