Skip to content

More convenient way to work with multipage /-layer tiffs #2064

@stackcoder

Description

@stackcoder

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(...),
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind: APImissing or awkward public APIs, maintainer choicetopic: formatsTowards better encoding format coverage

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions