1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-27 07:03:14 -04:00

Apply size hint to ImageCrateLoader::load

This commit is contained in:
Varphone Wong
2024-03-01 14:35:14 +08:00
parent 99f59690da
commit dfe49fc1c6
2 changed files with 53 additions and 6 deletions

View File

@@ -1,9 +1,6 @@
#![allow(deprecated)]
use egui::{mutex::Mutex, TextureOptions};
#[cfg(feature = "svg")]
use egui::SizeHint;
use egui::{mutex::Mutex, SizeHint, TextureOptions};
/// An image to be shown in egui.
///
@@ -220,6 +217,55 @@ pub fn load_image_bytes(image_bytes: &[u8]) -> Result<egui::ColorImage, egui::lo
))
}
fn calculate_size_for_hint(size: [usize; 2], hint: SizeHint) -> [usize; 2] {
match hint {
SizeHint::Size(w, h) => [w as usize, h as usize],
SizeHint::Height(h) => [size[0] * h as usize / size[1], h as usize],
SizeHint::Width(w) => [w as usize, size[1] * w as usize / size[0]],
SizeHint::Scale(scale) => {
let scale = scale.into_inner();
[
(size[0] as f32 * scale) as usize,
(size[1] as f32 * scale) as usize,
]
}
}
}
/// Load a (non-svg) image and resize it to the given size hint.
///
/// Requires the "image" feature. You must also opt-in to the image formats you need
/// with e.g. `image = { version = "0.24", features = ["jpeg", "png"] }`.
///
/// # Errors
/// On invalid image or unsupported image format.
#[cfg(feature = "image")]
pub fn load_image_bytes_for_size(
image_bytes: &[u8],
hint: SizeHint,
) -> Result<egui::ColorImage, String> {
crate::profile_function!();
let image = image::load_from_memory(image_bytes).map_err(|err| err.to_string())?;
let src_size = [image.width() as _, image.height() as _];
let dst_size = calculate_size_for_hint(src_size, hint);
let (image, size) = if src_size != dst_size {
let image = image.resize_exact(
dst_size[0] as u32,
dst_size[1] as u32,
image::imageops::FilterType::Lanczos3,
);
(image, dst_size)
} else {
(image, src_size)
};
let image_buffer = image.to_rgba8();
let pixels = image_buffer.as_flat_samples();
Ok(egui::ColorImage::from_rgba_unmultiplied(
size,
pixels.as_slice(),
))
}
/// Load an SVG and rasterize it into an egui image.
///
/// Requires the "svg" feature.

View File

@@ -53,7 +53,7 @@ impl ImageLoader for ImageCrateLoader {
Self::ID
}
fn load(&self, ctx: &egui::Context, uri: &str, _: SizeHint) -> ImageLoadResult {
fn load(&self, ctx: &egui::Context, uri: &str, hint: SizeHint) -> ImageLoadResult {
// three stages of guessing if we support loading the image:
// 1. URI extension (only done for files)
// 2. Mime from `BytesPoll::Ready`
@@ -95,7 +95,8 @@ impl ImageLoader for ImageCrateLoader {
// (3)
log::trace!("started loading {uri:?}");
let result = crate::image::load_image_bytes(&bytes).map(Arc::new);
let result =
crate::image::load_image_bytes_for_size(&bytes, hint).map(Arc::new);
log::trace!("finished loading {uri:?}");
cache.insert(uri.into(), result.clone());
result.map(|image| ImagePoll::Ready { image })