bevyengine/bevy · error · IntoDynamicImageError

Conversion into dynamic image not supported for {0:?}.

Error message

Conversion into dynamic image not supported for {0:?}.

What it means

IntoDynamicImageError::UnsupportedFormat is returned by Image::try_into_dynamic (crates/bevy_image/src/image_texture_conversion.rs:158-192) for any format outside its small whitelist: R8Unorm, Rg8Unorm, Rgba8UnormSrgb, and Bgra8UnormSrgb/Bgra8Unorm (the last two for screenshots). Every other TextureFormat — including the very common linear Rgba8Unorm — falls into the catch-all arm at line 187 and is rejected, because DynamicImage has no corresponding buffer type. The method's doc explicitly points to Image::convert for changing format first.

Source

Thrown at crates/bevy_image/src/image_texture_conversion.rs:200

                    data
                })
                .map(DynamicImage::ImageRgba8)
            }
            // Throw and error if conversion isn't supported
            texture_format => return Err(IntoDynamicImageError::UnsupportedFormat(texture_format)),
        }
        .ok_or(IntoDynamicImageError::UnknownConversionError(
            self.texture_descriptor.format,
        ))
    }
}

/// Errors that occur while converting an [`Image`] into a [`DynamicImage`]
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum IntoDynamicImageError {
    /// Conversion into dynamic image not supported for source format.
    #[error("Conversion into dynamic image not supported for {0:?}.")]
    UnsupportedFormat(TextureFormat),

    /// Encountered an unknown error during conversion.
    #[error("Failed to convert into {0:?}.")]
    UnknownConversionError(TextureFormat),

    /// Tried to convert an image that has no texture data
    #[error("Image has no texture data")]
    UninitializedImage,
}

#[cfg(test)]
mod test {
    use image::{GenericImage, Rgba};

    use super::*;

    #[test]

View on GitHub (pinned to 396ca72708)

Solutions

  1. Convert before extracting: image.convert(TextureFormat::Rgba8UnormSrgb) (Image::convert at image.rs:1565 returns Option<Image>) and call try_into_dynamic on the result.
  2. Or convert to R8Unorm/Rg8Unorm if you want Luma8/LumaA8 DynamicImages.
  3. When you control image creation, pick one of the four supported formats up front.
  4. Note Bgra8UnormSrgb/Bgra8Unorm are supported specifically so swapchain screenshots work — no manual swizzle needed.

Example fix

// before — linear RGBA8 is not convertible
let dyn_img = image.try_into_dynamic()?; // Err(UnsupportedFormat(Rgba8Unorm))

// after — convert to a supported format first
let dyn_img = image
    .convert(TextureFormat::Rgba8UnormSrgb)
    .ok_or_else(|| anyhow!("conversion failed"))?
    .try_into_dynamic()?;
Defensive patterns

Strategy: type-guard

Validate before calling

// ensure a convertible format before calling try_into_dynamic
let fmt = image.texture_descriptor.format;
if !is_dynamic_convertible(fmt) {
    image = image.convert(TextureFormat::Rgba8UnormSrgb).expect("format convertible");
}

Type guard

fn is_dynamic_convertible(fmt: TextureFormat) -> bool {
    matches!(
        fmt,
        TextureFormat::R8Unorm
            | TextureFormat::Rg8Unorm
            | TextureFormat::Rgba8UnormSrgb
            | TextureFormat::Bgra8UnormSrgb
            | TextureFormat::Bgra8Unorm
    )
}

Try / catch

match image.try_into_dynamic() {
    Ok(dyn_img) => { /* ... */ }
    Err(IntoDynamicImageError::UnsupportedFormat(fmt)) => {
        let dyn_img = image.convert(TextureFormat::Rgba8UnormSrgb)
            .expect("convert to supported format")
            .try_into_dynamic()?;
    }
    Err(IntoDynamicImageError::UninitializedImage) => { /* re-load with MAIN_WORLD */ }
    Err(IntoDynamicImageError::UnknownConversionError(fmt)) => { /* data/extent mismatch */ }
}

Prevention

When it happens

Trigger: Calling image.try_into_dynamic() on an Image created with TextureFormat::Rgba8Unorm (linear), Rgba16Unorm, or any 10-bit/12-bit/float format; post-processing camera render targets that were configured with linear RGBA8; converting images loaded with texture_format overrides in ImageLoaderSettings.

Common situations: Screenshot or thumbnail code following Image::convert or render-target reads; mixing up Rgba8Unorm and Rgba8UnormSrgb when constructing images manually; feeding bevy_render-extracted textures into `image`-crate based tooling.

Related errors


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/3617cec64d06d7d7. Report an issue: GitHub.