diff --git a/src/buffer.rs b/src/buffer.rs index bdfc7cfcb6..d134d674a1 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -7,8 +7,8 @@ use std::slice::{Chunks, ChunksMut}; use color::{ColorType, FromColor, Luma, LumaA, Rgb, Rgba, Bgr, Bgra}; use flat::{FlatSamples, SampleLayout}; -use dynimage::save_buffer; -use image::{GenericImage, GenericImageView}; +use dynimage::{save_buffer, save_buffer_with_format}; +use image::{GenericImage, GenericImageView, ImageFormat}; use traits::Primitive; use utils::expand_packed; @@ -768,6 +768,32 @@ where } } +impl ImageBuffer +where + P: Pixel + 'static, + Container: Deref, +{ + /// Saves the buffer to a file at the specified path in + /// the specified format. + /// + /// See [`save_buffer_with_format`](fn.save_buffer_with_format.html) for + /// supported types. + pub fn save_with_format(&self, path: Q, format: ImageFormat) -> io::Result<()> + where + Q: AsRef, + { + // This is valid as the subpixel is u8. + save_buffer_with_format( + path, + self, + self.width(), + self.height(), +

::COLOR_TYPE, + format, + ) + } +} + impl Deref for ImageBuffer where P: Pixel + 'static, diff --git a/src/dynimage.rs b/src/dynimage.rs index 79eb311214..7ed818ec8b 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -564,6 +564,20 @@ impl DynamicImage { p.save(path) }) } + + /// Saves the buffer to a file at the specified path in + /// the specified format. + /// + /// See [`save_buffer_with_format`](fn.save_buffer_with_format.html) for + /// supported types. + pub fn save_with_format(&self, path: Q, format: ImageFormat) -> io::Result<()> + where + Q: AsRef, + { + dynamic_map!(*self, ref p -> { + p.save_with_format(path, format) + }) + } } #[allow(deprecated)] @@ -881,6 +895,59 @@ fn save_buffer_impl( } } +/// Saves the supplied buffer to a file at the path specified +/// in the specified format. +/// +/// The buffer is assumed to have the correct format according +/// to the specified color type. +/// This will lead to corrupted files if the buffer contains +/// malformed data. Currently only jpeg, png, ico, bmp and +/// tiff files are supported. +pub fn save_buffer_with_format

( + path: P, + buf: &[u8], + width: u32, + height: u32, + color: color::ColorType, + format: ImageFormat, +) -> io::Result<()> +where + P: AsRef, +{ + // thin wrapper function to strip generics + save_buffer_with_format_impl(path.as_ref(), buf, width, height, color, format) +} + +fn save_buffer_with_format_impl( + path: &Path, + buf: &[u8], + width: u32, + height: u32, + color: color::ColorType, + format: ImageFormat, +) -> io::Result<()> { + let fout = &mut BufWriter::new(File::create(path)?); + + match format { + #[cfg(feature = "ico")] + image::ImageFormat::ICO => ico::ICOEncoder::new(fout).encode(buf, width, height, color), + #[cfg(feature = "jpeg")] + image::ImageFormat::JPEG => jpeg::JPEGEncoder::new(fout).encode(buf, width, height, color), + #[cfg(feature = "png_codec")] + image::ImageFormat::PNG => png::PNGEncoder::new(fout).encode(buf, width, height, color), + #[cfg(feature = "bmp")] + image::ImageFormat::BMP => bmp::BMPEncoder::new(fout).encode(buf, width, height, color), + #[cfg(feature = "tiff")] + image::ImageFormat::TIFF => tiff::TiffEncoder::new(fout) + .encode(buf, width, height, color) + .map_err(|e| io::Error::new(io::ErrorKind::Other, Box::new(e))), + _ => Err(io::Error::new( + io::ErrorKind::InvalidInput, + &format!("Unsupported image format image/{:?}", format)[..], + )), + } +} + /// Create a new image from a Reader pub fn load(r: R, format: ImageFormat) -> ImageResult { #[allow(deprecated, unreachable_patterns)] diff --git a/src/lib.rs b/src/lib.rs index 15acbc04da..31bcdf893b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,7 +62,7 @@ pub use traits::Primitive; // Opening and loading images pub use dynimage::{guess_format, load, load_from_memory, load_from_memory_with_format, open, - save_buffer, image_dimensions}; + save_buffer, save_buffer_with_format, image_dimensions}; pub use dynimage::DynamicImage::{self, ImageLuma8, ImageLumaA8, ImageRgb8, ImageRgba8, ImageBgr8, ImageBgra8};