Saving out PNGs: pointers appreciated.

Monkey Forums/Monkey Programming/Saving out PNGs: pointers appreciated.

Peeling(Posted 2015) [#1]
I'm currently working on an atlasing system which, for various reasons, has to be written in Monkey. I want to be able to spit out the resulting textures as PNGs, but I can't find any support for that. The alternative is to save them as raw data and then post-process in Photoshop, but I'd prefer to avoid the extra step if possible.

Time is of the essence, too, so if anyone has made progress in this direction and could help me out, that would be much appreciated :)

Thanks!


Pierrou(Posted 2015) [#2]
The only bit of code I know allowing to export images is Fred's one, here : http://www.monkey-x.com/Community/posts.php?topic=5528#61922 (==> BMP only)


impixi(Posted 2015) [#3]
What's your target platform?

For desktop targets, the "proper" way would be to wrap libpng (and also zlib) but if "time is of the essence" then that is not really an option.


Nobuyuki(Posted 2015) [#4]
internal tool? Use Imagemagick's convert.exe as a secondary step after exporting pixels using Fred's export function. Wrapping libpng is probably the way to go in the long run of course....


ImmutableOctet(SKNG)(Posted 2015) [#5]
Okay, so the first thing you need to do is setup libpng, which should come with the needed zlib code. You'll likely have to build these yourself, and of course move the correct files over. To my knowledge, you don't need to dynamically link to these if you don't want to. Don't quote me on that; you should probably read the licenses. Monkey doesn't use libpng for decoding, it uses stb (On the GLFW targets, anyway), which does not support encoding, therefore, we'll have to use libpng or a similar library. Project files and make-files are already provided by libpng, but if you want to build a different version of zlib, you'll want to grab CMake. Getting CMake is probably a good idea anyway. Library setup is per-compiler, so if you want to use both GCC/MinGW and MSVC, you'll have to set them both up. After that, external C++ code can be used through Monkey on its C++ based targets. MinGW/GCC is currently untested, so if you're using it/them, tell me if it causes major errors. Non-C++ targets are not supported by the code I'm posting (This may change in the future). They likely have their own ways of doing this, to begin with. Anyway, on to the actual code:

Here's a repository on GitHub. That code has only been tested with MSVC, at the moment. I'm basically just too lazy to compile zlib and libpng again. This was originally based on the code provided here. That being said, the original version found on that page is pretty awful, not to mention inefficient.

I'm not going to do the work for the specific situation you have, but that should allow you to re-save the image-data you retrieve with the 'opengl.gles11' module's 'LoadImageData' command. Array support is on the to-do list, but Monkey's not as open about them. That module was written with somewhat limited knowledge of libpng, so it may be inefficient.

This put me through way too much hell to implement. Seriously, I went an hour debugging everything, just to find out that I wrote "= NULL" instead of "== NULL". That was it. I can't tell if Monkey's made me pick of bad habits, or I honestly think C++ should use '=' for both assignment and comparison. I got so angry righting this module, you have no idea. AND IT WAS ALL BECAUSE OF ONE MISSING CHARACTER. Not to mention that the documentation for libpng is all over the place, so I had to debug it and make guesses about the names of the proper destruction commands; there shouldn't be any memory leaks now. That module is licensed under the MIT license, so you should be good to use it for commercial projects. Since this is currently C++ only, the targets you have at your disposal are mainly desktop targets (Could be useful for tools). iOS might also work, assuming you can get libpng working on it.

Well, anyway, I hope this helps. I know this doesn't put several images into an atlas (Something you might want to use an external tool for), but it should prove useful.


Peeling(Posted 2015) [#6]
That's fantastic, thanks :) I, too, find that a few weeks with Monkey has destroyed 20 years of C++ manners.

It's purely a tool thing. The only reason I want/need to use Monkey at all is that the atlasing process needs to leverage the UI script parser that's already in the app in order to make automatic decisions about how to group and pack images in different atlases. I'm mainly trying to find out if it's less painful to convince Monkey to save out images, or to port the bits of the parser to another platform :) What you've posted should definitely help me make that decision.

Cheers!


Fred(Posted 2015) [#7]
@Peeling: have a look at the Desktop forum section, not perfect (uncompressed) but it might help...


Peeling(Posted 2015) [#8]
Thanks all. I ended up going for a hybrid approach: get the app to compile and save a 'usage file' to express how and where the images are used in a simpler format, then write an external tool to read that file, create the atlases, and fire out a 'key' file for the game to remap its image references into the atlases.