1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
use std::io::{BufReader, Cursor};
use crate::{array_type, error::Error, Array};
use super::{Limits, Reader, Writer};
impl From<Limits> for image::Limits {
fn from(value: Limits) -> Self {
let mut out = Self::no_limits();
out.max_alloc = value.image_bytes;
out.max_image_width = value.image_dim;
out.max_image_height = value.image_dim;
out
}
}
impl Reader {
/// Read and decode an image.
pub fn image(&self, image: &Array<array_type::Image>) -> Result<image::DynamicImage, Error> {
let f = BufReader::new(self.array_bytes_reader(image)?);
let mut reader = image::ImageReader::new(f).with_guessed_format()?;
reader.limits(self.limits().into());
Ok(reader.decode()?)
}
}
impl Writer {
/// Write an image in PNG encoding.
///
/// This supports grayscale, grayscale + alpha, RGB, and RGBA, in 8 or 16 bits per channel.
pub fn image_png(
&mut self,
image: &image::DynamicImage,
) -> Result<Array<array_type::Image>, Error> {
let mut bytes = Vec::new();
image.write_to(&mut Cursor::new(&mut bytes), image::ImageFormat::Png)?;
self.image_bytes(&bytes)
}
/// Write an image in JPEG encoding.
///
/// Unlike PNG this is limited to 8-bit RGB and compression is lossy, but it will give
/// much better compression ratios. The JPEG compression level is set by the `quality`
/// argument, from 1 to 100. 90 is a reasonable level for preserving fine detail in the image,
/// while lower values will give a smaller file.
///
/// If you have an existing image in JPEG encoding you shouldn't be using this method,
/// instead add the raw bytes of the file with `writer.image_bytes(&bytes)` to avoid recompressing
/// the image and losing more detail.
pub fn image_jpeg(
&mut self,
image: &image::RgbImage,
quality: u8,
) -> Result<Array<array_type::Image>, Error> {
let mut bytes = Vec::new();
image.write_with_encoder(image::codecs::jpeg::JpegEncoder::new_with_quality(
&mut Cursor::new(&mut bytes),
quality.clamp(1, 100),
))?;
self.image_bytes(&bytes)
}
}