-
-
Notifications
You must be signed in to change notification settings - Fork 21.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JPG] Add ResourceSaverJPG. #60660
[JPG] Add ResourceSaverJPG. #60660
Conversation
Uses the default values of jpeg-compressor (same library we use for decompressing): Quality: 85 Chroma subsampling: H2V2 Single pass. Uses mozjpeg's default quantization tables instead of JPEG Annex K.
BIND_ENUM_CONSTANT(SUBSAPLING_Y_ONLY); | ||
BIND_ENUM_CONSTANT(SUBSAPLING_H1V1); | ||
BIND_ENUM_CONSTANT(SUBSAPLING_H2V1); | ||
BIND_ENUM_CONSTANT(SUBSAPLING_H2V2); | ||
BIND_ENUM_CONSTANT(SUBSAPLING_MAX); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: it should be "SUBSAMPLING" 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Y (grayscale) only. | ||
</constant> | ||
<constant name="SUBSAPLING_H1V1" value="1" enum="SubSamplingFactor"> | ||
YCbCr, no subsampling (H1V1, YCbCr 1x1x1, 3 blocks per MCU). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the terms 4:4:4/4:2:2/4:2:0 often used in the audiovisual community, so I suggest referring them here:
YCbCr, no subsampling (H1V1, YCbCr 1x1x1, 3 blocks per MCU). | |
YCbCr, no subsampling (H1V1, YCbCr 1x1x1, 3 blocks per MCU). Also called 4:4:4 chroma subsampling. |
YCbCr, no subsampling (H1V1, YCbCr 1x1x1, 3 blocks per MCU). | ||
</constant> | ||
<constant name="SUBSAPLING_H2V1" value="2" enum="SubSamplingFactor"> | ||
YCbCr, H2V1 subsampling (YCbCr 2x1x1, 4 blocks per MCU). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
YCbCr, H2V1 subsampling (YCbCr 2x1x1, 4 blocks per MCU). | |
YCbCr, H2V1 subsampling (YCbCr 2x1x1, 4 blocks per MCU). Also called 4:2:2 chroma subsampling. |
YCbCr, H2V1 subsampling (YCbCr 2x1x1, 4 blocks per MCU). | ||
</constant> | ||
<constant name="SUBSAPLING_H2V2" value="3" enum="SubSamplingFactor"> | ||
YCbCr, H2V2 subsampling (YCbCr 4x1x1, 6 blocks per MCU. Very common. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
YCbCr, H2V2 subsampling (YCbCr 4x1x1, 6 blocks per MCU. Very common. | |
YCbCr, H2V2 subsampling (YCbCr 4x1x1, 6 blocks per MCU. Also called 4:2:0 chroma subsampling. This is a common option, as it provides significant size reduction with little quality loss for photos. However, this option is not recommended for drawings as it negatively impacts quality in a noticeable way. |
It might be worth opening a proposal to detail some use cases for saving JPEGs from Godot. One use case that might come to mind is screenshots, but using PNG for screenshots is heavily favored nowadays thanks to its lossless nature. The downside is that saving PNG screenshots can take a while, making the game freeze temporarily while the screenshot is taken. This can be mostly resolved by moving PNG saving to a thread though. In contrast, saving a JPEG is much faster, but it will never be a lossless format (even at quality 100). |
I also wish to have openexr saving, but openexr was removed from the game templates by Calinou. It was used by the material maker and others. |
I didn't remove OpenEXR from export templates, as it was never present there in the first place. In fact, I was considering adding it in #42947, but I decided against it due to the added binary size. |
Do we have a proposal for the generic image i/o apis? |
AFAIK no, it needs to be written. |
Superseded by #62122. |
This PR adds the possibility to save an
ImageTexture
as jpg using the library default parameters:Or saving an
Image
via the exposedResourceSaverJPG
optionally setting custom encoding parameters:I'm opening this PR since it has been discussed in the meetings, and I'd like to leave a trace of this work, but I think we should change our
load_{format}_from_buffer
/save_{format}[_to_buffer]
to something like:load_from_buffer(const StringName &p_format, p_buffer)
.save_image(const StringName &p_format, const String &p_path, Dictionary p_options)
(wherep_options
is format specific).save_image_buffer(const StringName &p_format, Dictionary p_options)
.And add an
ImageSaver
similar toImageLoader
(i.e.ImageSaver::add_image_format_saver
/remove/etc)Note that format is a StringName and not an enum, because I think that way GDExtensions can interact better with it, and I believe this could be beneficial for other similar cases (godotengine/godot-proposals#2461, godotengine/godot-proposals#3726, godotengine/godot-proposals#676)
This work has been originally sponsored by Maffle LLC, and there is interest in contributing similar work as GDExtension for AVIF encoding/decoding (i.e. godotengine/godot-proposals#2461).