SDL and Visual Studio 2010 resources - c++

I have a simple question. I use SDL and SDL_image in my c++ program and image loading is fine from a single png file.
SDL_Surface *dot = NULL;
dot = load_image("dot.png");
But how can I load the png file if I add it to the resources? so I don't want to store in a png file next to the exe. Is it possible to load from the resources?
Tried
dot = load_image(MAKEINTRESOURCE(IDB_PNG1));
but it didn't work.

It is fully possible to load an image or something else into SDL from a windows resource. To do this you need to get the raw data and pass it to the appropriate RWOPS.
HMODULE hModule = GetModuleHandle(_T("myapp.exe"));
HRSRC hWhite = FindResource(hModule, MAKEINTRESOURCE(IDB_WHITE_PNG), _T("PNG"));
unsigned int white_size = SizeofResource(hModule, hWhite);
HGLOBAL hgWhite = LoadResource(hModule, hWhite);
unsigned char* white_data = (unsigned char*)LockResource(hgWhite);
SDL_Surface* white = IMG_Load_RW(SDL_RWFromConstMem(white_data, white_size), 1);
This assumes that you have something similar in your *.rc file:
IDB_WHITE_PNG PNG "White.png"

According to the MAKEINTRESOURCE documentation :
The return value should be passed only to functions which explicitly indicate that they accept MAKEINTRESOURCE as a parameter.
You don't give the content of load_image (BTW, please include the content of the functions you use in your question, you'll get better answers ...) but I bet it's not using its parameter to call one of the Windows SDK functions which accept MAKEINTRESOURCE ... as far as I know these resources are supposed to hold some specific Windows UI data like mouse cursors, icons, etc.. for use with Windows functions, not with other libraries like SDL, so I'm not surprised it doesn't work.

Related

Get png file data from a png stored as a Windows resource (c++) [duplicate]

This question already has answers here:
Load resource as byte array programmaticaly in C++
(2 answers)
How to load a custom binary resource in a VC++ static library as part of a dll?
(3 answers)
Closed 2 years ago.
I have a PNG resource stored in a Windows exe. I want to load the png resource and create a pointer to the png data that can be written to disk to create a png file. (FWIW, I don't actually create the file at this point; the data is initially written inside another file and saved as a png file later.) This is in an MFC (c++) project, but the solution doesn't need to use MFC.
I envision a function prototype like this:
void GetPngFromResource(int iResourceID, VOID* pPngFileData, DWORD* pwPngDataBytes);
I see that ::LoadBitmap(), ::LoadImage() and CImage::LoadFromResource() don't support png resource loading. When I do attempt to use LoadImage(), GetLastError() reports "The specified resource name cannot be found in the image file" (error 1814):
HBITMAP hBitmapImage = (HBITMAP)::LoadImage(::GetModuleHandle(0), MAKEINTRESOURCE(iResourceID), IMAGE_BITMAP, 0, 0, 0);
I know the resource exists, because I can get a handle to it using FindResource() (although I don't know how, or whether it is possible, to get the png file data from the HRSCR handle):
HRSCR h = FindResource(HINST_THISCOMPONENT, MAKEINTRESOURCE(iResourceID), L"PNG");
I have seen examples that create an HBITMAP from a png resource using gdi+, but I need to end up with png file data.
Thanks!
"john" deserves credit for this correct solution, as he led me to it (via comments) [yeah, the SO gods marked my question as a duplicate and I can't select this as the solution, but it is].
void GetPngFromResource(int iResourceID, void** ppPngFileData, DWORD* pwPngDataBytes)
{
HMODULE hMod = GetModuleHandle(NULL);
HRSRC hRes = FindResource(hMod, MAKEINTRESOURCE(iResourceID), _T("PNG"));
HGLOBAL hGlobal = LoadResource(hMod, hRes);
*ppPngFileData = LockResource(hGlobal);
*pwPngDataBytes = SizeofResource(hMod, hRes);
}
I've excluded error trapping for brevity.

Cannot get an image handle from a bitmap within the resources when using "LoadImageA()" and cannot understand why

I am trying to load an image resource using the LoadImageA() function, yet it doesn't work and I don't understand why.
Here's a bit of my code :
bool isRessource = IS_INTRESOURCE(107);
// Load the resource to the HGLOBAL.
HGLOBAL imageResDataHandle = LoadImageA(
NULL,
MAKEINTRESOURCEA(107),
IMAGE_BITMAP,
0,
0,
LR_SHARED
);
HRESULT hr = (imageResDataHandle ? S_OK : E_FAIL);
The image I want to load is a bitmap saved in the resources, and represented as such within resources.h:
#define IDB_BITMAP1 107
When I execute the code, isRessource is equal to true, yet hr is equal to E_FAIL.
Any idea as to why this is happening? I am using Visual Studio 2019, and I made the image using Gimp.
After making the same image with the same format on another application (I used "Krita") and importing it again, the image finally loads with the same code (I only changed the reference to the resource). I guess that all types of bitmaps made from Gimp won't work in Visual Studio (I tried most formats of bitmaps from Gimp).
The first link searched with LoadImage gimp as a keyword is enough to answer this question.
This is some useful information:
The bitmap exported by GIMP has a broken header. Specifically, the
code seems to not write the RGBA masks, which AFAIK are not optional
in a BITMAPV5HEADER. This misaligns and changes the size of the entire
extended header, incidentally making it look like a BITMAPV4HEADER,
which explains why most programs will still open it fine. Without
having done any testing, I'd guess LoadImage() is more picky about the
values in this extended header; returning NULL is how it indicates
failure.
By the way, when you import a bitmap, the system does not remind you that the format of the image is unknown?
Like:
After testing, use LoadImage to load such an image will return NULL, and GetLastError will also return 0.

Loading an image from a resource embedded in a dll

I'm developing a browser plugin (npapi) using FireBreath, and in it I'm trying to embed images which I need to load at runtime.
I've been search, reading and experimenting for two days now but I can't seem to make it work.
This is the code I ended up with:
HMODULE hModule;
LPCWSTR path = L"nptest.dll";
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, path, &hModule);
LPTSTR resourceName = MAKEINTRESOURCE(106);
HBITMAP bitmap = (HBITMAP) LoadImage(hModule, resourceName, IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
The loaded bitmap seems to be empty after the execution of this code, and I can't figure out why.
At first I tried to load a PNG image, and later realized that PNGs are not supported, so I just created a BMP file using the resource editor in VS2010.
I know for sure that the BMP (with id 106) is in the compiled DLL because I used PE Explorer to check inside the DLL.
Any ideas as for why it fails to load the image resource?
Thanks a lot.

Loading JPEG file from resources in MFC C++ application

The following code works correctly under Windows XP:
CImage image;
RECT destRect;
int nResource = 10;
CResourceStream stream(0, MAKEINTRESOURCE(nResource), _T("JPEG"));
HRESULT hr = image.Load(&stream);
image.Draw(hDC, destRect);
But on Windows 7 image.Load returns E_FAIL though creating CResourceStream reads JPEG file from resources correctly.
Debugging gives the following result:
GdipCreateBitmapFromStream returns InvalidParameter.
What the problem can be?
JPEG is a custom category in resource file.
At the end I used this solution from codeproject:
http://www.codeproject.com/KB/GDI-plus/cgdiplusbitmap.aspx
It is a thin wrapper for GDI+ which is able to load JPEG files (and others) under Windows 7 perfectly.
I believe you should use "JPG" not "JPEG".

Is there a way to preserve the BITMAPFILEHEADER when loading a Bitmap as a Windows resource?

I've been working on testing a few things out using SFML 1.4 (Simple and Fast Multimedia Library) with C++ and Visual C++ 2008 Express Edition. To avoid having external images with my graphical programs, I was testing out the sf::Image::LoadFromMemory(const char * Data, std::size_t SizeInBytes) function with Bitmap resources loaded using a simple resource script:
IDB_SPRITE BITMAP "sprite1.bmp"
In my code to load the image to create an sf::Image using this bitmap resource, I use the following procedure, consisting of Win32 API functions (I've excluded the code that checks to make sure the Win32 functions don't return NULL to shorten this a bit):
HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDB_SPRITE), RT_BITMAP);
HGLOBAL hResData = LoadResource(NULL, hResInfo);
char * resourceData = reinterpret_cast<char *>(LockResource(hResData));
After that, I use the sf::Image::LoadFromMemory function:
MyImage.LoadFromMemory(resourceData, SizeofResource(NULL, hResInfo));
However, this doesn't work (I get an unknown file type error). After some testing, I discovered that the bitmap data I pass to the LoadFromMemory function does not include the BITMAPFILEHEADER (the first 14 bytes), and I believe this is the cause of the unknown file type error.
I can restore the BITMAPFILEHEADER manually and get the LoadFromMemory function to work fine. However, I'm wondering if there is some way to preserve the BITMAPFILEHEADER in the resource data to avoid doing this?
Using a custom resource type will preserve the entire file. Change the resource script to utilize the RCDATA type as opposed to the BITMAP type:
IDB_SPRITE RCDATA "sprite1.bmp"
In the FindResource function call, use RT_RCDATA instead of RT_BITMAP:
HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDB_SPRITE), RT_RCDATA);
For more information:
RCDATA Resource
Resource Types
You can add file to resources as a custom resource instead of RT_BITMAP -- this will add file exactly as it is. Unless you also need to ::LoadImage() it.