Add ImageFormatSetting::Guess to image loader (#13575)
# Objective
- Allow using image assets that don't have an extensions and whose
format is unknown. This is useful for loading images from arbitrary HTTP
URLs.
## Solution
- This PR adds a new variant to `ImageFormatSetting` called `Guess`. The
loader will use `image::guess_format` to deduce the format based on the
content of the file.
## Testing
- I locally removed the extension of bevy_bird_dark, and ran a modified
version of the `sprite` example:
```rust
//! Displays a single [`Sprite`], created from an image.
use bevy::{
prelude::*,
render::texture::{ImageFormatSetting, ImageLoaderSettings},
};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(Camera2dBundle::default());
commands.spawn(SpriteBundle {
texture: asset_server
.load_with_settings("branding/bevy_bird_dark", |s: &mut ImageLoaderSettings| {
s.format = ImageFormatSetting::Guess
}),
..default()
});
}
```
## Changelog
### Added
`ImageFormatSetting::Guess` to automatically guess the format of an
image asset from its content.
Co-authored-by: François Mockers <mockersf@gmail.com>
This commit is contained in:
parent
06f733b16f
commit
31955cc78b
@ -109,6 +109,26 @@ impl ImageFormat {
|
||||
ImageFormat::Basis | ImageFormat::Ktx2 => return None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn from_image_crate_format(format: image::ImageFormat) -> Option<ImageFormat> {
|
||||
Some(match format {
|
||||
image::ImageFormat::Avif => ImageFormat::Avif,
|
||||
image::ImageFormat::Bmp => ImageFormat::Bmp,
|
||||
image::ImageFormat::Dds => ImageFormat::Dds,
|
||||
image::ImageFormat::Farbfeld => ImageFormat::Farbfeld,
|
||||
image::ImageFormat::Gif => ImageFormat::Gif,
|
||||
image::ImageFormat::OpenExr => ImageFormat::OpenExr,
|
||||
image::ImageFormat::Hdr => ImageFormat::Hdr,
|
||||
image::ImageFormat::Ico => ImageFormat::Ico,
|
||||
image::ImageFormat::Jpeg => ImageFormat::Jpeg,
|
||||
image::ImageFormat::Png => ImageFormat::Png,
|
||||
image::ImageFormat::Pnm => ImageFormat::Pnm,
|
||||
image::ImageFormat::Tga => ImageFormat::Tga,
|
||||
image::ImageFormat::Tiff => ImageFormat::Tiff,
|
||||
image::ImageFormat::WebP => ImageFormat::WebP,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Asset, Reflect, Debug, Clone)]
|
||||
|
||||
@ -51,6 +51,7 @@ pub enum ImageFormatSetting {
|
||||
#[default]
|
||||
FromExtension,
|
||||
Format(ImageFormat),
|
||||
Guess,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@ -100,6 +101,18 @@ impl AssetLoader for ImageLoader {
|
||||
ImageType::Extension(ext)
|
||||
}
|
||||
ImageFormatSetting::Format(format) => ImageType::Format(format),
|
||||
ImageFormatSetting::Guess => {
|
||||
let format = image::guess_format(&bytes).map_err(|err| FileTextureError {
|
||||
error: err.into(),
|
||||
path: format!("{}", load_context.path().display()),
|
||||
})?;
|
||||
ImageType::Format(ImageFormat::from_image_crate_format(format).ok_or_else(
|
||||
|| FileTextureError {
|
||||
error: TextureError::UnsupportedTextureFormat(format!("{format:?}")),
|
||||
path: format!("{}", load_context.path().display()),
|
||||
},
|
||||
)?)
|
||||
}
|
||||
};
|
||||
Ok(Image::from_buffer(
|
||||
#[cfg(all(debug_assertions, feature = "dds"))]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user