lumen_assets/loaders/
image.rs1use std::sync::Arc;
4
5use crate::{
6 AssetKind, AssetLoader, ImageData, LoadContext, LoadErrorKind, LoadedAsset, LoadedImage,
7 PixBytes,
8};
9
10pub const IMAGE_EXTENSIONS: &[&str] = &["png"];
17
18pub struct ImageLoader;
24
25impl AssetLoader for ImageLoader {
26 fn extensions(&self) -> &[&str] {
27 IMAGE_EXTENSIONS
28 }
29
30 fn kind(&self) -> AssetKind {
31 AssetKind::Image
32 }
33
34 fn load(&self, ctx: &LoadContext<'_>) -> Result<LoadedAsset, LoadErrorKind> {
35 let path = ctx.path();
36 let img = match ctx.bytes() {
40 Some(bytes) => image::load_from_memory(bytes)
41 .map_err(|e| LoadErrorKind::DecodeFailed(format!("{path:?}: {e}")))?,
42 None => match image::open(path) {
43 Ok(img) => img,
44 Err(image::ImageError::IoError(io)) => return Err(LoadErrorKind::from(io)),
45 Err(image::ImageError::Unsupported(e)) => {
46 return Err(LoadErrorKind::DecodeFailed(format!("{path:?}: {e}")));
47 }
48 Err(e) => return Err(LoadErrorKind::DecodeFailed(format!("{path:?}: {e}"))),
49 },
50 };
51 let rgba = img.to_rgba8();
52 let (width, height) = rgba.dimensions();
53 let pixels: Arc<[u8]> = Arc::from(rgba.into_raw());
54 let blob = peniko::Blob::new(Arc::new(PixBytes(pixels.clone())));
55 let data = ImageData {
56 width,
57 height,
58 rgba: pixels,
59 blob,
60 };
61 Ok(LoadedAsset::Image(LoadedImage(data.into())))
62 }
63}