Skip to content

Commit e1d84b4

Browse files
Add save button to twix (HULKs#1665)
* add save button to twix for saving camera image as png/jpeg * fix imports * update twix version to 0.9.3 * moved implementation of saving a jpeg image to an impl block of JpegImage * wip * removed some comments * format 'jpeg.rs'
1 parent 60ec10c commit e1d84b4

4 files changed

Lines changed: 49 additions & 3 deletions

File tree

‎Cargo.lock‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎crates/types/src/jpeg.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
use color_eyre::eyre;
12
use image::{codecs::jpeg::JpegEncoder, ImageBuffer, ImageError, Luma, RgbImage};
23
use serde::{Deserialize, Serialize};
4+
use std::path::Path;
35

46
use crate::{grayscale_image::GrayscaleImage, ycbcr422_image::YCbCr422Image};
57

@@ -36,3 +38,9 @@ impl TryFrom<&YCbCr422Image> for JpegImage {
3638
Ok(Self { data: jpeg_buffer })
3739
}
3840
}
41+
42+
impl JpegImage {
43+
pub fn save_to_jpeg_file(&self, file: impl AsRef<Path>) -> eyre::Result<()> {
44+
Ok(std::fs::write(file, self.data.clone())?)
45+
}
46+
}

‎tools/twix/Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "twix"
3-
version = "0.9.2"
3+
version = "0.9.3"
44
edition.workspace = true
55
license.workspace = true
66
homepage.workspace = true

‎tools/twix/src/panels/image/mod.rs‎

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::sync::Arc;
1+
use std::{env::temp_dir, fs::create_dir_all, path::PathBuf, sync::Arc};
22

33
use chrono::{DateTime, Utc};
44
use color_eyre::{eyre::eyre, Result};
@@ -7,6 +7,7 @@ use eframe::egui::{ColorImage, Response, SizeHint, TextureOptions, Ui, UiBuilder
77
use geometry::rectangle::Rectangle;
88
use image::RgbImage;
99
use linear_algebra::{point, vector};
10+
use log::{info, warn};
1011
use serde_json::{json, Value};
1112

1213
use types::{jpeg::JpegImage, ycbcr422_image::YCbCr422Image};
@@ -91,6 +92,24 @@ impl Panel for ImagePanel {
9192
}
9293
}
9394

95+
fn save_jpeg_image(buffer: &BufferHandle<JpegImage>, path: PathBuf) -> Result<()> {
96+
let buffer = buffer
97+
.get_last_value()?
98+
.ok_or_else(|| eyre!("no image available"))?;
99+
buffer.save_to_jpeg_file(&path)?;
100+
info!("image saved to '{}'", path.display());
101+
Ok(())
102+
}
103+
104+
fn save_raw_image(buffer: &BufferHandle<YCbCr422Image>, path: PathBuf) -> Result<()> {
105+
let buffer = buffer
106+
.get_last_value()?
107+
.ok_or_else(|| eyre!("no image available"))?;
108+
buffer.save_to_ycbcr_444_file(&path)?;
109+
info!("image saved to '{}'", path.display());
110+
Ok(())
111+
}
112+
94113
impl Widget for &mut ImagePanel {
95114
fn ui(self, ui: &mut Ui) -> Response {
96115
ui.horizontal(|ui| {
@@ -112,6 +131,25 @@ impl Widget for &mut ImagePanel {
112131
let date: DateTime<Utc> = timestamp.into();
113132
ui.label(date.format("%T%.3f").to_string());
114133
}
134+
if ui.button("Save").clicked() {
135+
let time_stamp = Utc::now().format("%H:%M:%S%.3f").to_string();
136+
let directory = temp_dir().join("twix");
137+
if let Err(error) = create_dir_all(&directory) {
138+
warn!("failed to create temporary folder /tmp/twix: {error}");
139+
} else {
140+
let cycler_name = format!("{:?}", self.cycler);
141+
let path = directory.join(format!("image_{cycler_name}_{time_stamp}.png"));
142+
let result = match &self.image_buffer {
143+
RawOrJpeg::Raw(buffer) => save_raw_image(buffer, path),
144+
RawOrJpeg::Jpeg(buffer) => {
145+
save_jpeg_image(buffer, path.with_extension("jpeg"))
146+
}
147+
};
148+
if let Err(error) = result {
149+
warn!("failed to save image: {error}");
150+
}
151+
}
152+
}
115153
});
116154
let (response, mut painter) = TwixPainter::allocate(
117155
ui,

0 commit comments

Comments
 (0)