Encoder ignores width & height
kkettinger opened this issue · 2 comments
When using EncoderOptions
and setting width and height, they are ignored in the resulting image. Setting the quality is not ignored.
Here a minimal example:
use std::fs::File;
use std::io::Read;
use std::path::Path;
use zune_image::codecs::bmp::zune_core::options::{DecoderOptions, EncoderOptions};
use zune_image::codecs::ImageFormat;
use zune_image::image::Image;
fn main() {
let file_path = "test.jpg";
let file_path_output = "output.jpg";
// Read file
let mut file = File::open(file_path).unwrap();
let mut data = Vec::new();
file.read_to_end(&mut data).unwrap();
// Convert to Image type
let image = Image::read(data, DecoderOptions::default()).unwrap();
// Encoder options
let encoder_options = EncoderOptions::default()
.set_width(100)
.set_height(100)
.set_quality(70);
println!("encoder options: {:?}", encoder_options);
// Encoder
let ext = Path::new(file_path_output).extension().unwrap();
let (_, mut encoder) = ImageFormat::get_encoder_for_extension(ext.to_str().unwrap()).unwrap();
encoder.set_options(encoder_options);
// Encode
let result = encoder.encode(&image).unwrap();
// Write file
std::fs::write(file_path_output, &result).unwrap();
// Display width & height for input & output
let image_output = Image::read(&result, DecoderOptions::default()).unwrap();
println!("input dimensions: {:?}", image.dimensions());
println!("output dimensions: {:?}", image_output.dimensions());
}
Output:
encoder options: EncoderOptions { width: 100, height: 100, colorspace: RGB, quality: 70, depth: Eight, num_threads: 4, effort: 4, flags: EncoderFlags { jpeg_encode_progressive: false, jpeg_optimize_huffman: false, image_strip_metadata: false } }
input dimensions: (3648, 2736)
output dimensions: (3648, 2736)
cargo.toml
zune-image = "0.4.14"
Hope you can help me out why the encoder ignores my dimensions. Thank you in advance.
Just found out the dimensions seem to be maximum dimensions for encoding/decoding, not for resizing the image.
There is a zune-imageprocs
crate that does resizing.
Here is a complete example for everyone interested:
use std::fs::File;
use std::io::Read;
use std::path::Path;
use zune_image::codecs::bmp::zune_core::options::{DecoderOptions, EncoderOptions};
use zune_image::codecs::ImageFormat;
use zune_image::image::Image;
use zune_image::traits::OperationsTrait;
use zune_imageprocs::resize::{Resize, ResizeMethod};
fn main() {
let file_path = "test.jpg";
let file_path_output = "output.jpg";
// Read file
let mut file = File::open(file_path).unwrap();
let mut data = Vec::new();
file.read_to_end(&mut data).unwrap();
// Image format
let (image_format, _) = ImageFormat::guess_format(&data).unwrap();
// Decoder options
let decoder_options = DecoderOptions::default();
// Decode
let mut decoder = image_format.get_decoder_with_options(&data, decoder_options).unwrap();
let mut image = decoder.decode().unwrap();
println!("input dimensions: {:?}", image.dimensions());
// Resize
Resize::new(1024, 1024, ResizeMethod::Bilinear).execute(&mut image).unwrap();
// Encoder options
let encoder_options = EncoderOptions::default()
.set_quality(70);
println!("encoder options: {:?}", encoder_options);
// Encoder
let ext = Path::new(file_path_output).extension().unwrap();
let (_, mut encoder) = ImageFormat::get_encoder_for_extension(ext.to_str().unwrap()).unwrap();
encoder.set_options(encoder_options);
// Encode
let result = encoder.encode(&image).unwrap();
// Write file
std::fs::write(file_path_output, &result).unwrap();
// Display output dimensions
let image_output = Image::read(&result, DecoderOptions::default()).unwrap();
println!("output dimensions: {:?}", image_output.dimensions());
}
Yes, sorry the encoder fills basic image information from the image itself.
The reason we still have it to set up additional parameters such as threading e.g if you have specific requirements for how many threads to be used for jxl encoding.