Turn PNG loading code to use a FILE instead of local resource
Вопрос
I'm working on a little softare which is meant to display a png file directly on the desktop. i've found a way of doing the later part with a HBITMAP strukture. Yet I've spent days by now searching for a way to load a .PNG file to such a HBITMAP.
The code I found eventuall (which I also could compile) was this one from this page:
http://logiklabs.tumblr.com/post/22946728048/how-to-load-an-image-resource-into-a-hbitmap
Think it would work perfectly. My problem is though that this one is meant to use already attached .png files.
Yet I need the possibility to use at runtime a file from an (at compile time) unknown location.
So how could I alter that script to achieve that? My C++ knowledge is not the best unfortunately and the MS-documentation of thsoe related functions did not really help either :/
I'd be very very thankful!
Решение
It looks like you can just load the PNG file into RAM and pass its address and length to stbi_load_from_memory()
. You basically change the first part of the code on the linked page to load the file into RAM, then proceed the same. Example below:
static HBITMAP LoadImageResource(LPCTSTR filename)
{
unsigned char *res_data, *splash_image;
DWORD res_size;
int width, height, components;
BITMAPV5HEADER bmh;
HBITMAP hBitmapRet;
FILE* f = _tfopen(filename, "rb");
if (!f)
return NULL;
fseek(f, 0, SEEK_END);
res_size = ftell(f);
rewind(f);
res_data = new unsigned char[res_size];
fread(res_data, sizeof(unsigned char), res_size, f);
fclose(f);
splash_image = stbi_load_from_memory(res_data, res_size, &width, &height, &components, 0);
ZeroMemory(&bmh, sizeof(BITMAPV5HEADER));
bmh.bV5Size = sizeof(BITMAPV5HEADER);
bmh.bV5Width = width;
bmh.bV5Height = -height;
bmh.bV5Planes = 1;
bmh.bV5BitCount = 32;
bmh.bV5Compression = BI_BITFIELDS;
bmh.bV5RedMask = 0x00FF0000;
bmh.bV5GreenMask = 0x0000FF00;
bmh.bV5BlueMask = 0x000000FF;
bmh.bV5AlphaMask = 0xFF000000;
hBitmapRet = CreateDIBitmap(GetDC(NULL), (BITMAPINFOHEADER *) &bmh, CBM_INIT,
splash_image, (BITMAPINFO *) &bmh, DIB_RGB_COLORS);
stbi_image_free(splash_image);
delete[] res_data;
return hBitmapRet;
}