gliscowo / isometric-renders

Creates high-resolution isometric screenshots of Minecraft's game objects
https://modrinth.com/mod/isometric-renders
MIT License
109 stars 13 forks source link

[Suggestion] Improve render file sizes / add post-processing configuration #56

Open qwerasd205 opened 1 year ago

qwerasd205 commented 1 year ago

Currently when saving renders the mod uses net.minecraft.client.texture.NativeImage's writeTo method, which ultimately calls STBImageWrite.nstbi_write_png_to_func which is frankly terrible at compression:

LWJGL JavaDoc for STBImageWrite

The PNG output is not optimal; it is 20-50% larger than the file written by a decent optimizing implementation; though providing a custom zlib compress function (see zlib_compress) can mitigate that. This library is designed for source code compactness and simplicity, not optimal image file size or run-time performance.

Solutions?

  1. Endeavor to provide a better zlib compress function, as suggested in the JavaDoc.
  2. Adjust stbi_write_png_compression_level global variable ("// defaults to 8; set to higher for more compression" - if it's normal zlib stuff I'd expect 9 to be the max, but it's somewhat vague).
  3. Don't use NativeImage to compress/write the file, instead use something like:
    • javax.imageio.ImageIO which has moderately better compression available, and a bit more control while you're at it.
    • pngtastic which does some extremely good compression of PNG images.
  4. If compressing in-memory before writing to disk is too tricky, the image can be written to disk and then have a compressor/optimizer called on it.

Additional nice-to-have:

  1. Compression options for animations, too:
    • APNG: Pngtastic
    • GIF: Gifsicle perhaps
    • MP4 (and also potentially both of the above) - just improve the parameters passed to FFmpeg. I'd be happy to help tune them for best results. (This is also something that could and, IMO, should, be user-configurable.)
  2. Config options for how exactly renders get processed before/after written to disk, ideally allowing fully custom commands to be configured to run on newly written renders.