Implement image resizing
This commit is contained in:
parent
9507d54585
commit
a2471bda0b
2 changed files with 95 additions and 4 deletions
76
src/image.rs
76
src/image.rs
|
@ -1,10 +1,12 @@
|
||||||
use std::{
|
use std::{
|
||||||
fs::read_dir,
|
fs::read_dir,
|
||||||
|
num::NonZeroU32,
|
||||||
path::Path
|
path::Path
|
||||||
};
|
};
|
||||||
|
|
||||||
use log::error;
|
use fast_image_resize as fr;
|
||||||
use image::{ImageBuffer, Rgb, ImageError};
|
use image::{ImageBuffer, Rgb, ImageError};
|
||||||
|
use log::{debug, error};
|
||||||
use smithay_client_toolkit::shm::slot::{Buffer, SlotPool};
|
use smithay_client_toolkit::shm::slot::{Buffer, SlotPool};
|
||||||
use smithay_client_toolkit::reexports::client::protocol::wl_shm;
|
use smithay_client_toolkit::reexports::client::protocol::wl_shm;
|
||||||
|
|
||||||
|
@ -16,6 +18,8 @@ pub fn workspace_bgs_from_output_image_dir(
|
||||||
format: wl_shm::Format,
|
format: wl_shm::Format,
|
||||||
brightness: i32,
|
brightness: i32,
|
||||||
contrast: f32,
|
contrast: f32,
|
||||||
|
surface_width: NonZeroU32,
|
||||||
|
surface_height: NonZeroU32,
|
||||||
)
|
)
|
||||||
-> Result<Vec<WorkspaceBackground>, String>
|
-> Result<Vec<WorkspaceBackground>, String>
|
||||||
{
|
{
|
||||||
|
@ -72,7 +76,48 @@ pub fn workspace_bgs_from_output_image_dir(
|
||||||
image = image.brighten(brightness)
|
image = image.brighten(brightness)
|
||||||
}
|
}
|
||||||
|
|
||||||
let image = image.into_rgb8();
|
let mut image = image.into_rgb8();
|
||||||
|
|
||||||
|
let Some(image_width) = NonZeroU32::new(image.width()) else {
|
||||||
|
error!(
|
||||||
|
"Image '{}' has zero width, skipping", workspace_name
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Some(image_height) = NonZeroU32::new(image.height()) else {
|
||||||
|
error!(
|
||||||
|
"Image '{}' has zero height, skipping", workspace_name
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
if image_width != surface_width || image_height != surface_height
|
||||||
|
{
|
||||||
|
debug!("Resizing image '{}' from {}x{} to {}x{}",
|
||||||
|
workspace_name,
|
||||||
|
image_width, image_height,
|
||||||
|
surface_width, surface_height
|
||||||
|
);
|
||||||
|
|
||||||
|
let src_image = fr::Image::from_vec_u8(
|
||||||
|
image_width,
|
||||||
|
image_height,
|
||||||
|
image.into_raw(),
|
||||||
|
fr::PixelType::U8x3,
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
let dst_image = resize_image_with_cropping(
|
||||||
|
src_image.view(),
|
||||||
|
surface_width,
|
||||||
|
surface_height,
|
||||||
|
);
|
||||||
|
|
||||||
|
image = ImageBuffer::from_raw(
|
||||||
|
surface_width.get(),
|
||||||
|
surface_height.get(),
|
||||||
|
dst_image.into_vec()
|
||||||
|
).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
let buffer = match format {
|
let buffer = match format {
|
||||||
wl_shm::Format::Xrgb8888 =>
|
wl_shm::Format::Xrgb8888 =>
|
||||||
|
@ -142,3 +187,30 @@ fn buffer_bgr888_from_image(
|
||||||
buffer
|
buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copied example from fast_image_resize
|
||||||
|
fn resize_image_with_cropping(
|
||||||
|
mut src_view: fr::DynamicImageView,
|
||||||
|
dst_width: NonZeroU32,
|
||||||
|
dst_height: NonZeroU32
|
||||||
|
) -> fr::Image {
|
||||||
|
// Set cropping parameters
|
||||||
|
src_view.set_crop_box_to_fit_dst_size(dst_width, dst_height, None);
|
||||||
|
|
||||||
|
// Create container for data of destination image
|
||||||
|
let mut dst_image = fr::Image::new(
|
||||||
|
dst_width,
|
||||||
|
dst_height,
|
||||||
|
src_view.pixel_type(),
|
||||||
|
);
|
||||||
|
// Get mutable view of destination image data
|
||||||
|
let mut dst_view = dst_image.view_mut();
|
||||||
|
|
||||||
|
// Create Resizer instance and resize source image
|
||||||
|
// into buffer of destination image
|
||||||
|
let mut resizer = fr::Resizer::new(
|
||||||
|
fr::ResizeAlg::Convolution(fr::FilterType::Lanczos3)
|
||||||
|
);
|
||||||
|
resizer.resize(&src_view, &mut dst_view).unwrap();
|
||||||
|
|
||||||
|
dst_image
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::path::PathBuf;
|
use std::{num::NonZeroU32, path::PathBuf};
|
||||||
|
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use smithay_client_toolkit::{
|
use smithay_client_toolkit::{
|
||||||
|
@ -160,6 +160,23 @@ impl OutputHandler for State {
|
||||||
output_name, width, height
|
output_name, width, height
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if !width.is_positive() {
|
||||||
|
error!(
|
||||||
|
"New output '{}' has a non-positive width: {}, skipping",
|
||||||
|
output_name,
|
||||||
|
width
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if !height.is_positive() {
|
||||||
|
error!(
|
||||||
|
"New output '{}' has a non-positive height: {}, skipping",
|
||||||
|
output_name,
|
||||||
|
height
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let surface = self.compositor_state.create_surface(qh);
|
let surface = self.compositor_state.create_surface(qh);
|
||||||
|
|
||||||
let layer = self.layer_shell.create_layer_surface(
|
let layer = self.layer_shell.create_layer_surface(
|
||||||
|
@ -185,7 +202,9 @@ impl OutputHandler for State {
|
||||||
&mut self.shm_slot_pool,
|
&mut self.shm_slot_pool,
|
||||||
pixel_format,
|
pixel_format,
|
||||||
self.brightness,
|
self.brightness,
|
||||||
self.contrast
|
self.contrast,
|
||||||
|
NonZeroU32::new(width as u32).unwrap(),
|
||||||
|
NonZeroU32::new(height as u32).unwrap()
|
||||||
) {
|
) {
|
||||||
Ok(workspace_bgs) => {
|
Ok(workspace_bgs) => {
|
||||||
debug!(
|
debug!(
|
||||||
|
|
Loading…
Add table
Reference in a new issue