heic2jpg

git clone git://archive.git.mtrnord.blog/MTRNord/heic2jpg.git
Log | Files | Refs | README | LICENSE

conversion_worker.rs (3998B)


      1 use magick_rust::{MagickError, MagickWand};
      2 use std::path::PathBuf;
      3 use std::result::Result;
      4 use tracing::info;
      5 use walkdir::WalkDir;
      6 
      7 use relm4::{ComponentSender, Worker};
      8 
      9 #[derive(Debug)]
     10 pub enum ConversionWorkerInputMsg {
     11     ConvertFolder(PathBuf, PathBuf),
     12 }
     13 
     14 #[derive(Debug)]
     15 pub enum ConversionWorkerMsg {
     16     ConversionStarted(usize),
     17     ProgressUpdate(f64),
     18     ConversionComplete,
     19     ConversionFailed(String),
     20 }
     21 
     22 pub struct ConversionWorker;
     23 
     24 impl Worker for ConversionWorker {
     25     type Init = ();
     26     type Input = ConversionWorkerInputMsg;
     27     type Output = ConversionWorkerMsg;
     28 
     29     fn init(_init: Self::Init, _sender: ComponentSender<Self>) -> Self {
     30         Self
     31     }
     32 
     33     fn update(&mut self, msg: ConversionWorkerInputMsg, sender: ComponentSender<Self>) {
     34         match msg {
     35             ConversionWorkerInputMsg::ConvertFolder(input_path, output_path) => {
     36                 // Walk directory, find all heic files, convert them to jpg and update progress
     37                 info!("Converting folder {:?}", input_path);
     38                 let result = self.convert_folder(input_path, output_path, &sender);
     39 
     40                 // Send the result of the conversion back
     41                 match result {
     42                     Ok(_) => sender
     43                         .output(ConversionWorkerMsg::ConversionComplete)
     44                         .unwrap(),
     45                     Err(e) => sender
     46                         .output(ConversionWorkerMsg::ConversionFailed(e.to_string()))
     47                         .unwrap(),
     48                 }
     49             }
     50         }
     51     }
     52 }
     53 
     54 impl ConversionWorker {
     55     fn convert_folder(
     56         &self,
     57         input_path: PathBuf,
     58         output_path: PathBuf,
     59         sender: &ComponentSender<Self>,
     60     ) -> Result<(), MagickError> {
     61         // Start the conversion
     62         info!("Converting folder {:?} to {:?}", input_path, output_path);
     63 
     64         // Use walkdir to find all heic files in the input directory
     65         let heic_files: Vec<PathBuf> = WalkDir::new(input_path)
     66             .follow_links(true)
     67             .same_file_system(false)
     68             .into_iter()
     69             .filter_map(|entry| {
     70                 let entry = entry.ok()?;
     71                 let path = entry.path();
     72                 let extension = path.extension();
     73                 //info!("Found file {:?}", path);
     74                 if path.is_file() && extension.map_or(false, |ext| ext.eq_ignore_ascii_case("heic"))
     75                 {
     76                     Some(path.to_path_buf())
     77                 } else {
     78                     None
     79                 }
     80             })
     81             .collect();
     82         info!("Found {} heic files", heic_files.len());
     83         sender
     84             .output(ConversionWorkerMsg::ConversionStarted(heic_files.len()))
     85             .unwrap();
     86 
     87         // Convert each heic file to jpg
     88         for (index, heic_file) in heic_files.iter().enumerate() {
     89             info!("Converting file {:?}", heic_file);
     90             let output_file = output_path
     91                 .join(heic_file.file_stem().unwrap())
     92                 .with_extension("jpg");
     93 
     94             // Convert the file
     95             self.convert_heic_to_jpg(heic_file.to_path_buf(), output_file)?;
     96 
     97             // Update the progress
     98             sender
     99                 .output(ConversionWorkerMsg::ProgressUpdate(
    100                     (index + 1) as f64 / heic_files.len() as f64,
    101                 ))
    102                 .unwrap();
    103         }
    104         info!("Conversion complete");
    105         Ok(())
    106     }
    107 
    108     fn convert_heic_to_jpg(
    109         &self,
    110         input_file: PathBuf,
    111         output_file: PathBuf,
    112     ) -> Result<(), MagickError> {
    113         // Create a MagickWand
    114         let mut wand = MagickWand::new();
    115 
    116         // Read the input file
    117         info!("Reading file {:?}", input_file);
    118         wand.read_image(input_file.to_str().unwrap())?;
    119 
    120         // Convert the image to jpg
    121         wand.set_image_format("jpg")?;
    122         info!("Converting to jpg");
    123         wand.write_image(output_file.to_str().unwrap())?;
    124 
    125         Ok(())
    126     }
    127 }