kitty_graphics_protocol/
image.rs1use crate::command::Command;
4use crate::error::Result;
5use crate::types::{Action, ImageFormat};
6use std::io::Write;
7use std::path::Path;
8
9pub struct ImageDisplay {
11 quiet: u8,
12}
13
14impl Default for ImageDisplay {
15 fn default() -> Self {
16 Self::new()
17 }
18}
19
20impl ImageDisplay {
21 pub fn new() -> Self {
23 Self { quiet: 2 }
24 }
25
26 pub fn quiet(mut self, mode: u8) -> Self {
28 self.quiet = mode;
29 self
30 }
31
32 pub fn display_png_file<P: AsRef<Path>>(&self, path: P) -> Result<()> {
34 let data = std::fs::read(path)?;
35 self.display_png(&data)
36 }
37
38 pub fn display_png(&self, data: &[u8]) -> Result<()> {
40 let chunks = Command::transmit_png(data)?;
41 let mut stdout = std::io::stdout().lock();
42 for chunk in chunks {
43 stdout.write_all(chunk.as_bytes())?;
44 }
45 stdout.flush()?;
46 Ok(())
47 }
48
49 pub fn display_rgba(&self, data: &[u8], width: u32, height: u32) -> Result<()> {
51 let chunks = Command::transmit_rgba(data, width, height)?;
52 let mut stdout = std::io::stdout().lock();
53 for chunk in chunks {
54 stdout.write_all(chunk.as_bytes())?;
55 }
56 stdout.flush()?;
57 Ok(())
58 }
59
60 pub fn display_rgb(&self, data: &[u8], width: u32, height: u32) -> Result<()> {
62 let chunks = Command::transmit_rgb(data, width, height)?;
63 let mut stdout = std::io::stdout().lock();
64 for chunk in chunks {
65 stdout.write_all(chunk.as_bytes())?;
66 }
67 stdout.flush()?;
68 Ok(())
69 }
70
71 pub fn clear_all(&self) -> Result<()> {
73 let cmd = Command::delete_all();
74 let seq = cmd.serialize(&[])?;
75 let mut stdout = std::io::stdout().lock();
76 stdout.write_all(seq.as_bytes())?;
77 stdout.flush()?;
78 Ok(())
79 }
80
81 pub fn transmit_png(&self, data: &[u8], image_id: u32) -> Result<()> {
83 let cmd = Command::builder()
84 .action(Action::Transmit)
85 .format(ImageFormat::Png)
86 .image_id(image_id)
87 .quiet(self.quiet)
88 .build();
89
90 let chunks: Vec<String> = cmd.serialize_chunked(data)?.collect();
91 let mut stdout = std::io::stdout().lock();
92 for chunk in chunks {
93 stdout.write_all(chunk.as_bytes())?;
94 }
95 stdout.flush()?;
96 Ok(())
97 }
98
99 pub fn place_image(&self, image_id: u32, cols: u32, rows: u32) -> Result<()> {
101 let cmd = Command::place(image_id, cols, rows);
102 let seq = cmd.serialize(&[])?;
103 let mut stdout = std::io::stdout().lock();
104 stdout.write_all(seq.as_bytes())?;
105 stdout.flush()?;
106 Ok(())
107 }
108}
109
110pub fn display_png<P: AsRef<Path>>(path: P) -> Result<()> {
112 ImageDisplay::new().display_png_file(path)
113}
114
115pub fn display_png_data(data: &[u8]) -> Result<()> {
117 ImageDisplay::new().display_png(data)
118}
119
120pub fn clear_all_images() -> Result<()> {
122 ImageDisplay::new().clear_all()
123}
124
125#[cfg(test)]
126mod tests {
127 use super::*;
128
129 #[test]
130 fn test_image_display_creation() {
131 let display = ImageDisplay::new().quiet(1);
132 assert_eq!(display.quiet, 1);
133 }
134}