c2pa-rs

A fork of https://github.com/contentauth/c2pa-rs/
git clone git://archive.git.mtrnord.blog/mtrnords-photography-manager/c2pa-rs.git
Log | Files | Refs | README

make_thumbnail.rs (2192B)


      1 // Copyright 2022 Adobe. All rights reserved.
      2 // This file is licensed to you under the Apache License,
      3 // Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
      4 // or the MIT license (http://opensource.org/licenses/MIT),
      5 // at your option.
      6 
      7 // Unless required by applicable law or agreed to in writing,
      8 // this software is distributed on an "AS IS" BASIS, WITHOUT
      9 // WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
     10 // implied. See the LICENSE-MIT and LICENSE-APACHE files for the
     11 // specific language governing permissions and limitations under
     12 // each license.
     13 
     14 use std::io::{Read, Seek};
     15 
     16 use anyhow::{Error, Result};
     17 use image::{io::Reader, ImageFormat};
     18 
     19 // max edge size allowed in pixels for thumbnail creation
     20 const THUMBNAIL_LONGEST_EDGE: u32 = 1024;
     21 const THUMBNAIL_JPEG_QUALITY: u8 = 80;
     22 
     23 ///  utility to generate a thumbnail from a stream
     24 /// returns Result (format, image_bits) if successful, otherwise Error
     25 pub fn make_thumbnail_from_stream<R: Read + Seek + ?Sized>(
     26     format: &str,
     27     stream: &mut R,
     28 ) -> Result<(String, Vec<u8>)> {
     29     let format = ImageFormat::from_extension(format)
     30         .or_else(|| ImageFormat::from_mime_type(format))
     31         .ok_or(Error::msg(format!("format not supported {format}")))?;
     32 
     33     let reader = Reader::with_format(std::io::BufReader::new(stream), format);
     34     let mut img = reader.decode()?;
     35 
     36     let longest_edge = THUMBNAIL_LONGEST_EDGE;
     37 
     38     // generate a thumbnail image scaled down and in jpeg format
     39     if img.width() > longest_edge || img.height() > longest_edge {
     40         img = img.thumbnail(longest_edge, longest_edge);
     41     }
     42 
     43     // for png files, use png thumbnails for transparency
     44     // for other supported types try a jpeg thumbnail
     45     let (output_format, format) = match format {
     46         ImageFormat::Png => (image::ImageOutputFormat::Png, "image/png"),
     47         _ => (
     48             image::ImageOutputFormat::Jpeg(THUMBNAIL_JPEG_QUALITY),
     49             "image/jpeg",
     50         ),
     51     };
     52     let thumbnail_bits = Vec::new();
     53     let mut cursor = std::io::Cursor::new(thumbnail_bits);
     54     img.write_to(&mut cursor, output_format)?;
     55 
     56     let format = format.to_owned();
     57     Ok((format, cursor.into_inner()))
     58 }