All Versions
Latest Version
Avg Release Cycle
32 days
Latest Release

Changelog History
Page 1

  • v0.24.4 Changes

    🆕 New Features:

    • Encoding for webp is now available with the native library. This needs to be activate explicitly with the web-encoder feature.
    • 👍 exr decoding has gained basic limit support.

    🐛 Bug fixes:

    • 🛠 The Iterator::size_hint implementation of pixel iterators has been fixed to return the current length indicated by its ExactSizeIterator hint.
    • 📚 Typos and bad references in the documentation have been removed.

    🐎 Performance:

    • ImageBuffer::get_pixel{,_mut} is now marked inline.
    • resize now short-circuits when image dimensions are unchanged.
  • v0.24.3 Changes

    🆕 New Features:

    • 👍 TiffDecoder now supports setting resource limits.

    🐛 Bug fixes:

    • 🛠 Fix compile issues on little endian systems.
    • Various panics discovered by fuzzing.
  • v0.24.2 Changes

    Structural changes:

    • CI now runs cargo-deny, checking dependent crates to an OSS license list and against RUSTSEC advisories.

    🆕 New Features:

    • The WebP decoder recognizes and decodes images with VP8X header.
    • The DDS decoder recognizes and decodes images with DX10 headers.

    🐛 Bug fixes:

    • Calling DynamicImage/ImageBuffer's methods write_to and save will now work properly even if the backing container is larger than the image layout requires. Only the relevant slice of pixel data is passed to the encoder.
    • 🛠 Fixed a OOM-panic caused by malformed images in the gif decoder.
  • v0.24.1 Changes

    🐛 Bug Fixes:

    • ImageBuffer::get_pixel_checked would sometimes return the incorrect pixel.
    • 👍 PNG encoding would sometimes not recognize unsupported color.
  • v0.24.0 Changes

    💥 Breaking changes

    Structural changes:

    • Minimum Rust version is now 1.56 and may change in minor versions until further notice. It is now tracked in the library's Cargo.toml, instead, by the standard [package.rust-version] field. Note: this applies to the library itself. You may need different version resolutions for dependencies when using a non-stable version of Rust.
    • 🚚 The math::utils::{nq, utils} modules have been removed. These are better served through the color_quant crate and the standard library respectively.
    • All codecs are now available through image::codecs, no longer top-level.
    • ExtendedColorType and DynamicImage have been made #[non_exhaustive], providing more methods instead of exhaustive matching.
    • Reading images through the generic io::Reader, as well as generic convenience interfaces, now requires the underlying reader to be BufRead + Seek. This allows more efficient support more formats. Similarly, writing now requires writers to be Write + Seek.
    • 👍 The Bgra* variants of buffers, which were only half-supported, have been removed. The owning buffer types ImageBuffer and DynamicImage fundamentally already make a choice in supported pixel representations. This allows for more consistent internal behavior. Callers are expected to convert formats when using those buffers, which they are required to do in any case already, and which is routinely performed by decoders.

    Trait reworks:

    • The Pixel trait is no longer implemented quite as liberally for structs defined in the crate. Instead, it is now restricted to a set of known channel which ensures accuracy in computations involving those channels.
    • The ImageDecoderExt trait has been renamed to ImageDecoderRect, according to its actual functionality.
    • The Pixel trait and its Subpixel field no longer require (or provide) a 'static lifetime bound.
    • The Pixel trait no longer requires specifying an associated, constant ColorType. This was of little relevance to computation but made it much harder to implement and extend correctly. Instead, the private PixelWithColorType extension is added for interfaces that require a properly known variant.
    • Reworked how SubImage interacts with the GenericImage trait. It is now a default implementation. Note that SubImage now has inherent methods that avoid double-indirection, the trait's method will no longer avoid this.
    • The Primitive trait now requires implementations to provide a minimum and maximum logical bound for the purpose of converting to other primitive representations.

    ➕ Additions

    Image formats:

    • 👍 Reading lossless WebP is now supported.
    • 👍 The OpenEXR format is now supported.
    • ⬆️ The jpeg decoder has been upgraded to Lossless JPEG.
    • The AvifEncoder now correctly handles alpha-less images. Some additional color formats are converted to RGBA as well.
    • The Bmp codec now decodes more valid images. It can decode a raw image without performing the palette mapping. It provides a method to access the palette. The encoder provides the inverse capabilities.
    • Tiff is now an output format.

    Buffers and Operations:

    • 👍 The channel / primitive type f32 is now supported. Currently only the OpenEXR codec makes full use of it but this is expected to change.
    • ImageBuffer::{get_pixel_checked, get_pixel_mut_checked} provide panic-free access to pixels and channels by returning Option<&P> and Option<&mut P>.
    • ImageBuffer::write_to has been added, encoding the buffer to a writer. This method already existed on DynamicImage.
    • 👍 DynamicImage now implements From<_> for all supported buffer types.
    • 0️⃣ DynamicImage now implements Default, an empty Rgba8 image.
    • imageops::overlay now takes coordinates as i64.


    • ➕ Added Limits and LimitSupport, utilized in io::Reader. These can be configured for rudimentary protection against resource exhaustion (images pretending to require a very large buffer). These types are not yet exhaustive by design, and more and stricter limits may be added in the future.
    • 👍 Encoders that do provide inherent support for limits, or reserve a significant amount of internal memory, are urged to implement the set_limits extension to ImageDecoder. Some strict limit are opt-in, which may cause decoding to fail if not supported.


    • PNMSubtype has been renamed to PnmSubtype, by Rust's naming scheme.
    • 🚚 Several incorrectly capitalized PNM* aliases have been removed.
    • Several enum types that had previously used a hidden variant now use the official #[non_exhaustive] attribute instead.
  • v0.23.14 Changes

    • Unified gif blending in different decode methods, fixing out-of-bounds checks in a number of weirdly positioned frames.
    • Hardened TGA decoder against a number of malicious inputs.
    • 🛠 Fix forward incompatible usage of the panic macro.
    • 🛠 Fix load_rect for gif reaching unreachable!() code.

    • ➕ Added ExtendedColorType::A8.

    • 👍 Allow TGA to load alpha-only images.

    • ⚡️ Optimized load_rect to avoid unnecessary seeks.

  • v0.23.13 Changes

    • 🛠 Fix an inconsistency in supported formats of different methods for encoding an image.
    • 🛠 Fix thumbnail choosing an empty image. It now always prefer non-empty image dimensions.
    • 🛠 Fix integer overflow in calculating requires bytes for decoded image buffers for farbfeld, hdr, and pnm decoders. These will now error early.
    • 🛠 Fix a panic decoding certain jpeg image without frames or meta data.
    • ⚡️ Optimized the jpeg encoder.
    • ⚡️ Optimized GenericImage::copy_from default impl in various cases.

    • ➕ Add avif decoders. You must enable it explicitly and it is not covered by our usual MSRV policy of Rust 1.34. Instead, only latest stable is supported.

    • Add ImageFormat::{can_read, can_write}

    • ➕ Add Frame::buffer_mut

    • ➕ Add speed and quality options on avif encoder.

    • ➕ Add speed parameter to gif encoder.

    • 🔦 Expose control over sequence repeat to the gif encoder.

    • Add {contrast,brighten,huerotate}_in_place functions in imageproc.

    • 0️⃣ Relax Default impl of ImageBuffer, removing the bound on the color type.

    • Derive Debug, Hash, PartialEq, Eq for DynamicImage

  • v0.23.12 Changes

    • Fix a soundness issue affecting the impls of Pixel::from_slice_mut. This would previously reborrow the mutable input reference as a shared one but then proceed to construct the mutable result reference from it. While UB according to Rust's memory model, we're fairly certain that no miscompilation can happen with the LLVM codegen in practice. See 5cbe1e6767d11aff3f14c7ad69a06b04e8d583c7 for more details.
    • 🛠 Fix imageops::blur panicking when sigma = 0.0. It now defaults to 1.0 as all negative values.
    • 🛠 Fix re-exporting png::{CompressionType, FilterType} to maintain SemVer compatibility with the 0.23 releases.

    • ➕ Add ImageFormat::from_extension

    • ➕ Add copyless DynamicImage to byte slice/vec conversion.

    • Add bit-depth specific into_ and to_ DynamicImage conversion methods.

  • v0.23.11 Changes

    • The NeuQuant implementation is now supplied by color_quant. Use of the type defined by this library is discouraged.
    • The jpeg decoder can now downscale images that are decoded by 1,2,4,8.
    • ⚡️ Optimized the jpeg encoding ~5-15%.
    • 🗄 Deprecated the clamp function. Use num-traits instead.
    • The ICO decoder now accepts an empty mask.
    • 🛠 Fixed an overflow in ICO mask decoding potentially leading to panic.
    • ➕ Added ImageOutputFormat for AVIF
    • 🐎 Updated tiff to 0.6 with lzw performance improvements.
  • v0.23.10 Changes

    • ➕ Added AVIF encoding capabilities using the ravif crate. Please note that the feature targets the latest stable compiler and is not enabled by default.
    • ➕ Added ImageBuffer::as_raw to inspect the underlying container.
    • 🐎 Updated gif to 0.11 with large performance improvements.