Loading images from resources.rc

23 views
Skip to first unread message

Christian

unread,
Feb 18, 2025, 12:17:03 PMFeb 18
to fltk.coredev
Hello, I understand that it is possible to load images into a fltk window if the images are in the directory of the executable. However I am wondering if it is supported with fltk to load images from resource if they are included in a resources.rc file beforehand then loaded in to the application. In order to avoid having to ship many image files along with my application, I would rather bundle them in if possible.

So far I am unsuccessful but what I think I am seeing is that this code requires the .png file to be in the directory of the application at runtime:

const char* name = "VTLogo1.png";
Fl_PNG_Image *img = new Fl_PNG_Image(name);
if (img->w() == 0 || img->h() == 0)
{
fl_message("Can't open icon file '%s'",name);
exit(1);
}

// set icon or do something with the image
main_window.icon(img);

Albrecht Schlosser

unread,
Feb 18, 2025, 12:40:15 PMFeb 18
to fltkc...@googlegroups.com
On 2/18/25 17:42 Christian wrote:
Hello, I understand that it is possible to load images into a fltk window if the images are in the directory of the executable. However I am wondering if it is supported with fltk to load images from resource if they are included in a resources.rc file beforehand then loaded in to the application. In order to avoid having to ship many image files along with my application, I would rather bundle them in if possible.

First of all, this is the wrong group to ask such questions, fltk.coredev is used to discuss the development of the FLTK library and not to ask questions about using it. The correct group would be fltk.general (see link below). But read on...


So far I am unsuccessful but what I think I am seeing is that this code requires the .png file to be in the directory of the application at runtime:

const char* name = "VTLogo1.png";
Fl_PNG_Image *img = new Fl_PNG_Image(name);
if (img->w() == 0 || img->h() == 0)
{
fl_message("Can't open icon file '%s'",name);
exit(1);
}

// set icon or do something with the image
main_window.icon(img);

FLTK allows you to load many image types from memory, particularly PNG images. Your topic "Loading images from resources.rc" would be Windows specific, but there are better ways that work on all platforms. I can't help with the Windows resource file approach but I recommend cross-platform ways anyway.

(1) The "manual" way: convert the bits and bytes of a PNG image file to a compileable array of char's. There are several ways to do this, on Linux you could use `xxd -1 name-of-png-file`. The description in the man page is: "Output in C include file style. A complete static array definition is written (named after the input file), unless xxd reads from stdin."

Then you can copy this static array definition in a source file and compile it anywhere in your program and eventually use it to load the image from the memory defined above with the constructor:

Fl_PNG_Image::Fl_PNG_Image(const char *name_png, const unsigned char *buffer, int maxsize)

where the buffer and size must be taken from the static PNG image array defined above. The rest of your code would be the same as if you had loaded it from an image file.

For more details see the docs at https://www.fltk.org/doc-1.4/classFl__PNG__Image.html#ae8f77a54a4cef7cb04203036b04e1b62


(2) As the docs say, the second way is to use FLTK's tool `fluid`, at least to "convert" the image file to a static array in C/C++ code as you would do with `xxd` in method (1) - if you don't use fluid anyway in your app.

How to use fluid best in your case I can't tell (I'm personally not a fluid user). Others may chime in to give examples if you need.

If you need more help, please move to fltk.general (https://groups.google.com/g/fltkgeneral) and ask there again.

Albrecht Schlosser

unread,
Feb 18, 2025, 12:44:01 PMFeb 18
to fltkc...@googlegroups.com
Correction:

On 2/18/25 18:40 'Albrecht Schlosser' wrote:
`xxd -1 name-of-png-file`

This should read: `xxd -i name-of-png-file` (replace "-1" with "-i", a lowercase 'I').

Christian

unread,
Feb 18, 2025, 1:11:52 PMFeb 18
to fltk.coredev
Thank you I had no idea fluid supported adding binary data directly. I got this working in 5 minutes after going through your response. My apologies, still new to fltk I will be sure to post in the correct group.

-Christian

Albrecht Schlosser

unread,
Feb 18, 2025, 1:25:04 PMFeb 18
to fltkc...@googlegroups.com
On 2/18/25 19:05 Christian wrote:
Thank you I had no idea fluid supported adding binary data directly. I got this working in 5 minutes after going through your response.

Great, I'm glad I could help.


My apologies, still new to fltk I will be sure to post in the correct group.

No apologies needed, all new users are welcome, and guiding to the right group is no issue.

BTW, meanwhile we opened GitHub Discussions (Q&A) for such user questions which will likely be our main "Q&A Forum" in the future. Feel free to ask there as well...

Anyway, since I created an example, I'm going to post it here just in case other readers need one. Note that I'm leaving the conversion from an image file to binary data as an exercise to the user.

Here is a working example that's using the "manual" approach.

image.cxx:

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_PNG_Image.H>
#include "clock.cxx" // binary image data
int main(int argc, char **argv) {
auto window = new Fl_Double_Window(300, 300);
auto box = new Fl_Box(20, 20, 260, 260);
auto img = new Fl_PNG_Image(nullptr, clock_png, clock_png_len);
if (img && !img->fail())
box->image(img);
else
box->label("no image");
window->end();
window->show(argc, argv);
return Fl::run();
}

    clock.cxx (created from 'clock.png'  by `xxd -i clock.png`):

unsigned char clock_png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x64,
// ... more data ...
0xb4, 0x44, 0xd2, 0xe8, 0x85, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e,
0x44, 0xae, 0x42, 0x60, 0x82
};
unsigned int clock_png_len = 3233;

    
Compile with

  fltk-config --use-images --compile image.cxx

This works because `clock.cxx` is included by `image.cxx` (a quick hack).

Reply all
Reply to author
Forward
0 new messages