iced_core/window/
screenshot.rs
1use crate::{Rectangle, Size};
3
4use bytes::Bytes;
5use std::fmt::{Debug, Formatter};
6
7#[derive(Clone)]
11pub struct Screenshot {
12 pub bytes: Bytes,
14 pub size: Size<u32>,
16 pub scale_factor: f64,
19}
20
21impl Debug for Screenshot {
22 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
23 write!(
24 f,
25 "Screenshot: {{ \n bytes: {}\n scale: {}\n size: {:?} }}",
26 self.bytes.len(),
27 self.scale_factor,
28 self.size
29 )
30 }
31}
32
33impl Screenshot {
34 pub fn new(
36 bytes: impl Into<Bytes>,
37 size: Size<u32>,
38 scale_factor: f64,
39 ) -> Self {
40 Self {
41 bytes: bytes.into(),
42 size,
43 scale_factor,
44 }
45 }
46
47 pub fn crop(&self, region: Rectangle<u32>) -> Result<Self, CropError> {
50 if region.width == 0 || region.height == 0 {
51 return Err(CropError::Zero);
52 }
53
54 if region.x + region.width > self.size.width
55 || region.y + region.height > self.size.height
56 {
57 return Err(CropError::OutOfBounds);
58 }
59
60 const PIXEL_SIZE: usize = 4;
62
63 let bytes_per_row = self.size.width as usize * PIXEL_SIZE;
64 let row_range = region.y as usize..(region.y + region.height) as usize;
65 let column_range = region.x as usize * PIXEL_SIZE
66 ..(region.x + region.width) as usize * PIXEL_SIZE;
67
68 let chopped = self.bytes.chunks(bytes_per_row).enumerate().fold(
69 vec![],
70 |mut acc, (row, bytes)| {
71 if row_range.contains(&row) {
72 acc.extend(&bytes[column_range.clone()]);
73 }
74
75 acc
76 },
77 );
78
79 Ok(Self {
80 bytes: Bytes::from(chopped),
81 size: Size::new(region.width, region.height),
82 scale_factor: self.scale_factor,
83 })
84 }
85}
86
87impl AsRef<[u8]> for Screenshot {
88 fn as_ref(&self) -> &[u8] {
89 &self.bytes
90 }
91}
92
93impl From<Screenshot> for Bytes {
94 fn from(screenshot: Screenshot) -> Self {
95 screenshot.bytes
96 }
97}
98
99#[derive(Debug, thiserror::Error)]
100pub enum CropError {
102 #[error("The cropped region is out of bounds.")]
103 OutOfBounds,
105 #[error("The cropped region is not visible.")]
106 Zero,
108}