From 60f8dd0e53c516af6bb0ba4814c660a8d6ef33c1 Mon Sep 17 00:00:00 2001 From: SL91994 <320sl91994@gmail.com> Date: Mon, 13 May 2024 15:59:26 +0900 Subject: [PATCH] add: Option to convert single image. --- src/main.rs | 25 +++++++++++++++++++++++-- src/video_processing.rs | 27 +++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index b7f153c..922adc3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,11 +17,16 @@ struct Cli { #[arg(short, long, value_name = "URL")] url: Option, - /// Enter the path of the video you wish to convert. (Supported extensions: mp4, mkv) + /// Enter the path of the video you wish to convert. (Supported extensions: mp4, mkv...) /// Note: Since the conversion is based on the terminal size at the time this option is executed, a terminal of a different size will not be drawn correctly. #[arg(short, long, value_name = "CONVERT_VIDEO_PATH")] file_path: Option, + /// Enter the path of the image you want to convert. (Supported extensions: png, jpeg...) + /// Note: Terminals of different sizes will not render correctly as the conversion is based on the terminal size at the time this option is executed. + #[arg(short, long, value_name = "CONVERT_IMAGE_PATH")] + image_path: Option, + /// Play ascii_video with the converted image already prepared in tmp. #[arg(short, long)] play: bool, @@ -44,7 +49,7 @@ async fn download_video(url: &str) -> PathBuf { /// Arguments /// * `file_path` - The path to the video file to process. /// Returns -/// * `None`` +/// * `None` async fn process_video(file_path: &PathBuf) { let terminal = Terminal::new(); let tmp_dir = current_dir().unwrap().join("tmp"); @@ -52,6 +57,18 @@ async fn process_video(file_path: &PathBuf) { processor.convert_to_grayscale_and_frame().await; } +/// Performs the conversion process for the image of the given file path. +/// Arguments +/// * `file_path` - The path to the image file to process. +/// Returns +/// * `None` +async fn process_image(file_path: &PathBuf) { + let terminal = Terminal::new(); + let tmp_dir = current_dir().unwrap().join("tmp"); + let processor = VideoProcessor::new(Some(file_path.to_path_buf()), Some(tmp_dir), &terminal); + processor.convert_to_grayscale_and_resize().await; +} + #[tokio::main] async fn main() { let cli = Cli::parse(); @@ -64,6 +81,10 @@ async fn main() { process_video(&file_path.to_path_buf()).await; } + if let Some(image_path) = cli.image_path.as_deref() { + process_image(&image_path.to_path_buf()).await; + } + if cli.play { let terminal = Terminal::new(); let processor = VideoProcessor::new(None, None, &terminal); diff --git a/src/video_processing.rs b/src/video_processing.rs index dbc0d64..7bf9c77 100644 --- a/src/video_processing.rs +++ b/src/video_processing.rs @@ -86,6 +86,29 @@ impl VideoProcessor { assert!(status.success()); } + pub async fn convert_to_grayscale_and_resize(&self) { + let output_format = match &self.output_dir { + Some(dir) => dir.join("single_output.png"), + None => PathBuf::from("single_output.png"), + }; + + // fps24で画像生成し、グレースケールに変換した後、ターミナルサイズに合わせて画像をリサイズする。 + let status = Command::new("ffmpeg") + .arg("-i") + .arg(self.video_path.as_ref().unwrap().to_str().unwrap()) + .arg("-vf") + .arg(format!( + "format=gray, scale={}:{}", + self.terminal.width.unwrap(), + self.terminal.height.unwrap() + )) + .arg(output_format.to_str().unwrap()) + .status() + .expect("Failed to execute command"); + + assert!(status.success()); + } + /// Converts the image to ASCII art representation. /// /// ## Arguments @@ -96,8 +119,8 @@ impl VideoProcessor { /// /// The ASCII art representation of the image as a vector of strings. pub async fn convert_image_to_ascii_art(&self, img: &DynamicImage) -> Vec { - // let ascii_brightness = ['@', '#', 'S', '%', '?', '*', '+', ';', ':', ',', '.']; - let ascii_brightness = [' ', ' ', ' ', ' ', '+', '*', '?', '%', 'S', '#', '@']; + let ascii_brightness = ['@', '#', 'S', '%', '?', '*', '+', ';', ':', ',', '.']; + // let ascii_brightness = [' ', ' ', ' ', ' ', '+', '*', '?', '%', 'S', '#', '@']; let (width, height) = img.dimensions(); let mut ascii_art = Vec::new();