Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions libharuhishot/src/screenshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,50 @@ impl HaruhiShotState {
region: area,
})
}
/// Capture all outputs and concatenate them horizontally.
/// The resulting image width is the sum of all output widths,
/// and each output image is copied side-by-side into the new image.
pub fn capture_all_outputs(
&mut self,
option: CaptureOption,
) -> Result<ImageInfo, HaruhiError> {
let outputs = self.outputs().clone();

let mut images: Vec<ImageInfo> = Vec::with_capacity(outputs.len());
for output in outputs.into_iter() {
let image = self.capture_single_output(option, output)?;
images.push(image);
}

if images.is_empty() {
return Err(HaruhiError::CaptureFailed("No outputs found".to_owned()));
}

let total_width: u32 = images.iter().map(|img| img.width).sum();
let max_height: u32 = images.iter().map(|img| img.height).max().unwrap_or(0);
// RGBA8: 4 bytes per pixel
let bytes_per_pixel: u32 = 4;
let mut combined: Vec<u8> = vec![0u8; (total_width * max_height * bytes_per_pixel) as usize];

let mut x_offset: u32 = 0;
for img in &images {
for row in 0..img.height {
let src_start = (row * img.width * bytes_per_pixel) as usize;
let src_end = src_start + (img.width * bytes_per_pixel) as usize;
let dst_start = ((row * total_width + x_offset) * bytes_per_pixel) as usize;
let dst_end = dst_start + (img.width * bytes_per_pixel) as usize;
combined[dst_start..dst_end].copy_from_slice(&img.data[src_start..src_end]);
}
x_offset += img.width;
}

Ok(ImageInfo {
data: combined,
width: total_width,
height: max_height,
color_type: images[0].color_type,
})
}
}

struct AreaShotInfo {
Expand Down
11 changes: 11 additions & 0 deletions src/clapargs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,15 @@ pub enum HaruhiCli {
},
#[command(long_flag = "color", short_flag = 'C', about = "get color")]
Color,
#[command(
long_flag = "all-outputs",
short_flag = 'A',
about = "capture all outputs and concatenate horizontally"
)]
AllOutputs {
#[arg(value_name = "stdout", long)]
stdout: bool,
#[arg(value_name = "pointer", long, default_value = "false")]
cursor: bool,
},
}
13 changes: 13 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,15 @@ pub fn waysip_to_region(
Ok(Region { position, size })
}

fn capture_all_outputs(
state: &mut HaruhiShotState,
use_stdout: bool,
pointer: bool,
) -> Result<HaruhiShotResult, HaruhiImageWriteError> {
let image_info = state.capture_all_outputs(pointer.to_capture_option())?;
write_to_image(image_info, use_stdout)
}

fn main() {
tracing_subscriber::fmt()
.with_writer(std::io::stderr)
Expand Down Expand Up @@ -296,6 +305,10 @@ fn main() {
HaruhiCli::Color => {
notify_result(get_color(&mut state));
}
HaruhiCli::AllOutputs {
stdout,
cursor: pointer,
} => notify_result(capture_all_outputs(&mut state, stdout, pointer)),
}
}

Expand Down