Closed quiet-bear closed 1 year ago
I can confirm the same behaviour on Linux. I think the image
crate that we use to save images has some default compression level. The quick solution would be to set compression to the lowest, if this setting is available in image
. A more long-term solution would be to have a window where you can set the JPEG compression level when exporting.
The image
crate does have a compression quality that is defaulted to 75 on a scale from worst quality (1) to best (100). I took a look at this issue and it seems that the best way to have fine control over the encoder is to use it directly:
pub fn save_image<IMG: Bitmap>(bitmap: IMG, path: &str) {
let bytes = bitmap.bytes();
let width = bitmap.width() as u32;
let height = bitmap.height() as u32;
let color = image::ColorType::Rgba8;
let file = std::fs::File::create(path).expect("Failed to create file from path");
let buffer = std::io::BufWriter::new(file);
let result = match ImageFormat::from_path(path)
.unwrap_or(ImageFormat::Png)
.into()
{
ImageOutputFormat::Png => {
codecs::png::PngEncoder::new(buffer).write_image(bytes, width, height, color)
}
ImageOutputFormat::Jpeg(_) => codecs::jpeg::JpegEncoder::new_with_quality(buffer, 100)
.write_image(bytes, width, height, color),
_ => return, // Format not supported
};
result.expect("Failed to save image");
}
This does resolve JPEG compression by calling new_with_quality
and bypassing the default quality. It might also be preferable in the future to have direct access to the encoders anyways.
Looks good to me, it's a pretty minimal change.
I'll get another PR created in a bit here.
OS: Windows 11
Exporting to JPEG artifacts the image (doing what JPEG does best). However, in the case of pixel art, I don't believe the compression should be this bad. Since there's no option for setting compression level, JPEG doesn't seem viable for smaller images at the moment. It might be good to set compression to the lowest it can go and revisit whenever there's a dedicated menu for tweaking export settings.
Imports don't seem to be affected.
Steps to reproduce: