image
image copied to clipboard
More convenient way to work with multipage /-layer tiffs
I would like to be able to read all images of a tiff file.
My specific use case for this functionality is writing code working with multiple instances of DynamicImage. Unfortunately there is no easy way to access next_image of tiff::decoder::Decoder without heavily duplicating the wrapper code.
Following is the closest I was able to get:
fn tiff_load_layers<R: io::BufRead + io::Seek>(r: &mut R) -> Result<Vec<image::DynamicImage>, Box<dyn Error>> {
let mut layers: Vec<image::DynamicImage> = Vec::new();
let mut raw = tiff::decoder::Decoder::new(r)?;
loop {
let layer = tiff_read_image(&mut raw)?;
layers.push(layer);
if !raw.more_images() {
break;
}
raw.next_image()?
}
Ok(layers)
}
fn tiff_read_image<R: io::BufRead + io::Seek>(raw: &mut tiff::decoder::Decoder<R>) -> Result<image::DynamicImage, Box<dyn Error>> {
let (width, height) = raw.dimensions()?;
let color_type = raw.colortype()?;
let pixels = raw.read_image()?;
// this code is likely `DynamicImage::from_decoder`
let image = match (color_type, pixels) {
(tiff::ColorType::RGB(8), tiff::decoder::DecodingResult::U8(pixels)) =>
image::ImageBuffer::from_vec(width, height, pixels).map(image::DynamicImage::ImageRgb8),
_ => None,
};
match image {
Some(image) => Ok(image),
None => Err(...),
}
}
This is an area of the API that could use some improvement. I collected some initial observations in #1894, but didn't do much as far as actually figuring out a common API that would work across formats