I'd like to pinpoint this FLTK technique that allows to have the pixeldata of a single image
re-used to draw this image any number of times in any width and height.
1) start from an Fl_RGB_Image object, let's call it rgb
2) create any number of Fl_Shared_Image objects constructed from rgb in 1):
Fl_Shared_Image *sh1 = Fl_Shared_Image::get(rgb, 0); // notice the second argument
Fl_Shared_Image *sh2 = Fl_Shared_Image::get(rgb, 0);
Fl_Shared_Image *sh3 = Fl_Shared_Image::get(rgb, 0);
All these share the same pixel data (present once in memory).
3) give to these Fl_Shared_Image objects the desired drawing size of each:
sh1->scale(W1, H1); // this will preserve the aspect ratio of rgb
sh2->scale(W2, H2, 0); // this will authorize change in the aspect ratio
sh3->scale(W3, H3);
4) use these Fl_Shared_Image objects in the GUI
5) destroy all of that, when images are no longer used, with:
sh1->release();
sh2->release();
sh3->release();
delete rgb; // must be last
With this technique, the image data exist only once in memory, and its cached form
also exists once. The scaled drawing capacity of the hardware is used to draw
the unique cached image to diversely sized window areas. This capacity is native
on MacOS and MSWindows. It requires Xrender under X11.
Member function Fl_Shared_Image::scale() is in FLTK 1.3.4 but requires building with
FL_ABI_VERSION >= 10304. It is also in FLTK 1.4 of course.
//==================== example toy program ===========
#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Shared_Image.H>
#include <FL/Fl_PNG_Image.H>
#include <FL/Fl_Window.H>
int main()
{
Fl_Window *win = new Fl_Window(400,400);
Fl_Button *b = new Fl_Button(10,10,260,130,0);
Fl_Button *b2 = new Fl_Button(10,150,50,100,0);
win->end();
win->show();
const char *fname = "/path/to/an/image.png";
Fl_RGB_Image *original = new Fl_PNG_Image(fname);
Fl_Shared_Image *scaleable = Fl_Shared_Image::get(original, 0);
b->image(scaleable);
b->align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER | FL_ALIGN_CLIP);
scaleable->scale(b->w(), b->h()); // keep image's aspect ratio
Fl_Shared_Image *scaleable2 = Fl_Shared_Image::get(original, 0);
b2->image(scaleable2);
b2->align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER | FL_ALIGN_CLIP);
scaleable2->scale(b2->w(), b2->h(), 0); // alter image's aspect ratio
Fl::run();
scaleable->release();
scaleable2->release();
delete original;
return 0;
}
//=============================