From 8c3c3051ac6dbf9192c61de27928ea0274316d0b Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 15 Aug 2022 20:23:27 +0200 Subject: [PATCH] screenshot: Replace image with png crate --- Cargo.lock | 37 +++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 +- src/input/mod.rs | 21 ++++++++++++++++----- src/state.rs | 9 ++++----- 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0fe8b55..685b2920 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,6 +33,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "ahash" version = "0.7.6" @@ -301,6 +307,7 @@ dependencies = [ "indexmap", "lazy_static", "libsystemd", + "png", "regex", "ron", "sendfd", @@ -342,6 +349,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-channel" version = "0.5.6" @@ -413,6 +429,15 @@ dependencies = [ "syn", ] +[[package]] +name = "deflate" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" +dependencies = [ + "adler32", +] + [[package]] name = "digest" version = "0.10.3" @@ -1169,6 +1194,18 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +[[package]] +name = "png" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc38c0ad57efb786dd57b9864e5b18bae478c00c824dc55a38bbc9da95dde3ba" +dependencies = [ + "bitflags", + "crc32fast", + "deflate", + "miniz_oxide", +] + [[package]] name = "ppv-lite86" version = "0.2.16" diff --git a/Cargo.toml b/Cargo.toml index 1b9f6c6a..0e36a4ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ serde_json = "1" sendfd = "0.4.1" egui = { version = "0.18.1", optional = true } edid-rs = { version = "0.1" } -#image = { version = "0.24.3", default-features = false, features = ["png"] } +png = "0.17.5" lazy_static = "1.4.0" thiserror = "1.0.26" regex = "1" diff --git a/src/input/mod.rs b/src/input/mod.rs index be91cad5..4f236a48 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -12,7 +12,7 @@ use smithay::{ backend::input::{Device, DeviceCapability, InputBackend, InputEvent, KeyState}, desktop::{layer_map_for_output, Kind, WindowSurfaceType}, reexports::wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle, Resource}, - utils::{Logical, Point, Rectangle}, + utils::{Logical, Point, Rectangle, Size, Buffer}, wayland::{ data_device::set_data_device_focus, output::Output, @@ -402,21 +402,32 @@ impl State { break; } }; - /* for output in self.common.shell.outputs.clone().into_iter() { match self.backend.offscreen_for_output(&output, &mut self.common) { - Ok(buffer) => { + Ok((buffer, size)) => { let mut path = std::path::PathBuf::new(); path.push(&home); path.push(format!("{}_{}.png", output.name(), timestamp)); - if let Err(err) = buffer.save(&path) { + + fn write_png(path: impl AsRef, data: Vec, size: Size) -> anyhow::Result<()> { + use std::{io, fs}; + + let file = io::BufWriter::new(fs::File::create(&path)?); + let mut encoder = png::Encoder::new(file, size.w as u32, size.h as u32); + encoder.set_color(png::ColorType::Rgba); + encoder.set_depth(png::BitDepth::Eight); + let mut writer = encoder.write_header()?; + writer.write_image_data(&data)?; + Ok(()) + } + + if let Err(err) = write_png(&path, buffer, size) { slog_scope::error!("Unable to save screenshot at {}: {}", path.display(), err); } }, Err(err) => slog_scope::error!("Could not save screenshot for output {}: {}", output.name(), err), } } - */ } } } diff --git a/src/state.rs b/src/state.rs index 8f3d6627..d1f70ce2 100644 --- a/src/state.rs +++ b/src/state.rs @@ -32,6 +32,7 @@ use smithay::{ shm::ShmState, viewporter::ViewporterState, }, + utils::{Size, Buffer}, }; use std::{ @@ -204,12 +205,11 @@ impl BackendData { } } - /* pub fn offscreen_for_output( &mut self, output: &Output, state: &mut Common, - ) -> anyhow::Result, Vec>> { + ) -> anyhow::Result<(Vec, Size)> { use anyhow::Context; use smithay::{ backend::{ @@ -230,7 +230,7 @@ impl BackendData { renderer: &mut R, output: &Output, state: &mut Common, - ) -> anyhow::Result, Vec>> + ) -> anyhow::Result<(Vec, Size)> where E: std::error::Error + Send + Sync + 'static, T: Clone + 'static, @@ -261,7 +261,7 @@ impl BackendData { let mapping = renderer.copy_framebuffer(Rectangle::from_loc_and_size((0, 0), size))?; let data = Vec::from(renderer.map_texture(&mapping)?); - Ok(image::ImageBuffer::from_raw(size.w as u32, size.h as u32, data).with_context(|| "buffer smaller then dimensions")?) + Ok((data, size)) } match self { @@ -277,7 +277,6 @@ impl BackendData { BackendData::Unset => unreachable!(), } } - */ } impl State {