liballeg / allegro5

The official Allegro 5 git repository. Pull requests welcome!
https://liballeg.org
Other
1.9k stars 286 forks source link

Get size of image from the file #1320

Open rmbeer opened 2 years ago

rmbeer commented 2 years ago

It's a feature (or function) that is missing in Allegro. It's a function that returns the size of an image from a file without the need to load the image first with al_load_bitmap().

Something like: al_get_size_image_file(char file, int width, int * height);

katastic commented 2 years ago

It couldn't be too hard to chop out the data loading code from al_load_bitmap or whatever and just leave the width/height parsing of the header. I don't know how many people need it though. Most people either load, or don't load, pictures into their game.

MarkOates commented 2 years ago

Allegro relies on external libraries to load image data, but I'm not sure they support loading specific pieces of data without first loading the whole image itself.

If you wanted to write the code specifically for your project, it shouldn't be too pull out width/height from the header for the specific file types that you're using (like PNG). Here's a few links:

Some formats may not have width/height in the header however, or, may not load properly.

katastic commented 2 years ago

That's a great point.

This would be fine for some sort of helper code (and apparently more difficult than I first thought). But I'd have to ask what use-case most games would have a use for it unless we put it into some sort of "image manipulation extras" code/header file you can optionally add to your project. Like I said earlier, 99% of games load an image, or don't.

We already have addons... but we more-or-less have all of those "addons" included always. Nobody ships Allegro DLLs without them all. So I think this would be better suited to an external library/header/source file if anyone were to add this, and if it's good enough, we can provide links to it (or include it as an optional in Allegro).

The easiest thing I would do in my game, if I needed this exact scenario, would be use some simple bash/batch scripting with an image tool (even ffmpeg) and simply dump that data to JSON/YAML/CSV. ffmpeg (image-magick, etc) are proven, tested tools, with tons of documentation and tutorials to dump data like this (ffprobe can load images!), and then dump the data into a suitable file format of

"FILE_NAME",width,height "FILE_NAME",width,height "FILE_NAME",width,height

Then your main program loads this file and parses it. Which will be super fast, and many AAA games cache things like that in metadata lists.

The bash script could be called with the build process, or only when files change (there's very very likely a bash/batch code for re-running a script when a directory of files changes), or simply manually when you add new images.

You could also, using just Allegro and your normal C/C++ skills, make a separate utility that loads the files, gets the width/height, caches those values to CSV/JSON/YAML, and your main program uses that. That won't require any additional skills than you would have just using Allegro normally.

It'd be way easier than understanding and modifying Allegro code (+libpng for pngs, and libwhatever for bitmaps, GIFS, JPEGs, etc)

So to summarize:

And absolute worst case, unless you're loading tens of thousands of images, getting with w,h, and then dumping the results (then just cache them like I mentioned above), it's really not "that" slow to load tons of files. I mean, it is slow compared to calculating SQRT, or sorting an array.

But honestly I'm struggling to find I use case for a game programming library, where you need to load files, get their header information, but then throw away the bitmap data. But not store that header information for later. I need to know more about the use case to help you--though regardless since it's not a simple couple-liner code change to add w/h I suggest that it's not applicable to Allegro--but much more applicable to a general purpose image tool, image library, or even an [Image Library to Allegro] binder library that allows them to integrate together. But then if you're just using width and height but not drawing anything, again, Allegro doesn't even need to be involved, right?

MarkOates commented 2 years ago

So I think this would be better suited to an external library/header/source file if anyone were to add this, and if it's good enough, we can provide links to it (or include it as an optional in Allegro).

I agree this is probably not a feature for Allegro. You mentioned several cases where external tools can be used to extract the data, dump it to a JSON, and have it on-hand from an externally generated list for loading at runtime.

Also, this approach is the common practice in web software as well. Image files are usually just dumped to the webpage during load-time and the page resizes the dimensions to fit. If the UI insists that the dimensions of the images are known before load-time (to avoid jumpy loading UI), then the dimensions are pre-loaded when the image record is created in the server's database long before the page requests it, and that data is sent down the pipe separately from the image itself.