diff options
| author | Sakarias Johansson <sakarias.johansson@goodbyekansas.com> | 2023-03-13 22:00:44 +0100 |
|---|---|---|
| committer | Sakarias Johansson <sakarias.johansson@goodbyekansas.com> | 2023-03-13 22:23:18 +0100 |
| commit | f19c8cc40c5caf8abb4f04aaf9f91ec3a8c1ccbc (patch) | |
| tree | a54a074ece82eafd8793cd0fb68a1b938286c923 /racer-tracer/src/image_action.rs | |
| parent | 3cabf77da8b9681ed9683fe92c23054d6f49d848 (diff) | |
| download | racer-tracer-f19c8cc40c5caf8abb4f04aaf9f91ec3a8c1ccbc.tar.gz racer-tracer-f19c8cc40c5caf8abb4f04aaf9f91ec3a8c1ccbc.tar.xz racer-tracer-f19c8cc40c5caf8abb4f04aaf9f91ec3a8c1ccbc.zip | |
📸 Add Camera defocus blur + Other
Just wanted to add defocus blur but ended up changing a bunch of other
this as well.
- Moved scenes to a separate folder.
- Updated readme with more pretty images.
- Add interface for loading scenes. There is currently one for yaml
and another if you want a slightly random scene.
- Add image action to decide what to do with the final image once its
rendered. Currently supports just showing the buffer until you press
the render buffer again and saving the image as `png`.
- When you use nix shell you will be dropped in the proper folder so
you can just do cargo build etc without having to do `cd`.
Diffstat (limited to 'racer-tracer/src/image_action.rs')
| -rw-r--r-- | racer-tracer/src/image_action.rs | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/racer-tracer/src/image_action.rs b/racer-tracer/src/image_action.rs new file mode 100644 index 0000000..825c506 --- /dev/null +++ b/racer-tracer/src/image_action.rs @@ -0,0 +1,111 @@ +use std::{path::PathBuf, sync::RwLock}; + +use sha2::{Digest, Sha256}; +use synchronoise::SignalEvent; + +use crate::{ + config::{Config, ImageAction as CImageAction}, + error::TracerError, +}; + +pub trait ImageAction: Send + Sync { + fn action( + &self, + screen_buffer: &RwLock<Vec<u32>>, + event: &SignalEvent, + config: &Config, + ) -> Result<(), TracerError>; +} + +impl From<&CImageAction> for Box<dyn ImageAction> { + fn from(image_action: &CImageAction) -> Self { + match image_action { + CImageAction::WaitForSignal => Box::new(WaitForSignal::new()), + CImageAction::SavePng => Box::new(SavePng::new()), + } + } +} + +pub struct SavePng {} + +impl SavePng { + pub fn new() -> Self { + Self {} + } +} + +impl ImageAction for SavePng { + fn action( + &self, + screen_buffer: &RwLock<Vec<u32>>, + _event: &SignalEvent, + config: &Config, + ) -> Result<(), TracerError> { + screen_buffer + .read() + .map_err(|e| TracerError::FailedToAcquireLock(e.to_string())) + .map(|buf| { + // Convert ARGB8 to RGBA8 + buf.iter() + .map(|v| { + let a: u32 = (v >> 24) & 0xff; + let r: u32 = (v >> 16) & 0xff; + let g: u32 = (v >> 8) & 0xff; + let b: u32 = v & 0xff; + + (r << 24) | (g << 16) | (b << 8) | a + }) + .flat_map(|val| val.to_be_bytes()) + .collect::<Vec<u8>>() + }) + .and_then(|buf| match &config.image_output_dir { + Some(image_dir) => { + println!("Saving image..."); + let mut sha = Sha256::new(); + + sha.update(buf.as_slice()); + + let mut file_path = PathBuf::from(image_dir); + file_path.push(format!("{:X}.png", sha.finalize())); + + img::save_buffer( + file_path.as_path(), + buf.as_slice(), + config.screen.width as u32, + config.screen.height as u32, + img::ColorType::Rgba8, + ) + .map_err(|e| { + let error = e.to_string(); + TracerError::ImageSave(error) + }) + .map(|_| { + println!("Saved image to: {}", file_path.to_string_lossy()); + }) + } + None => Ok(()), + }) + } +} + +pub struct WaitForSignal {} + +impl WaitForSignal { + pub fn new() -> Self { + Self {} + } +} + +impl ImageAction for WaitForSignal { + fn action( + &self, + _screen_buffer: &RwLock<Vec<u32>>, + event: &SignalEvent, + _config: &Config, + ) -> Result<(), TracerError> { + println!("Press R to resume."); + event.wait(); + event.reset(); + Ok(()) + } +} |
