uni_ocr/
lib.rs

1use anyhow::Result;
2pub use custom_ocr::Credentials;
3use image::DynamicImage;
4use std::time::Duration;
5
6#[derive(Debug, Clone)]
7pub enum OcrProvider {
8    Auto,
9    MacOS,
10    Windows,
11    Tesseract,
12    Custom { credentials: Credentials },
13}
14
15#[derive(Debug, Clone)]
16pub struct OcrOptions {
17    languages: Vec<Language>,
18    confidence_threshold: f32,
19    timeout: Duration,
20}
21
22impl Default for OcrOptions {
23    fn default() -> Self {
24        Self {
25            languages: vec![Language::English],
26            confidence_threshold: 0.0,
27            timeout: Duration::from_secs(30),
28        }
29    }
30}
31
32impl OcrOptions {
33    pub fn languages(mut self, langs: Vec<Language>) -> Self {
34        self.languages = langs;
35        self
36    }
37
38    pub fn confidence_threshold(mut self, threshold: f32) -> Self {
39        self.confidence_threshold = threshold;
40        self
41    }
42
43    pub fn timeout(mut self, timeout: Duration) -> Self {
44        self.timeout = timeout;
45        self
46    }
47}
48
49pub struct OcrEngine {
50    provider: OcrProvider,
51    options: OcrOptions,
52}
53
54impl OcrEngine {
55    pub fn new(provider: OcrProvider) -> Result<Self> {
56        Ok(Self {
57            provider,
58            options: OcrOptions::default(),
59        })
60    }
61
62    pub fn with_options(mut self, options: OcrOptions) -> Self {
63        self.options = options;
64        self
65    }
66
67    pub async fn recognize_image(
68        &self,
69        image: &DynamicImage,
70    ) -> Result<(String, String, Option<f64>)> {
71        match &self.provider {
72            #[cfg(target_os = "macos")]
73            OcrProvider::MacOS => Ok(perform_ocr_apple(image, &self.options.languages)),
74            OcrProvider::Windows => {
75                #[cfg(target_os = "windows")]
76                {
77                    perform_ocr_windows(image).await
78                }
79                #[cfg(not(target_os = "windows"))]
80                {
81                    Err(anyhow::anyhow!(
82                        "Windows OCR is not available on this platform"
83                    ))
84                }
85            }
86            OcrProvider::Tesseract => {
87                Ok(perform_ocr_tesseract(image, self.options.languages.clone()))
88            }
89            OcrProvider::Custom { credentials } => {
90                perform_ocr_custom(image, self.options.languages.clone(), &credentials).await
91            }
92            OcrProvider::Auto => {
93                #[cfg(target_os = "macos")]
94                {
95                    Ok(perform_ocr_apple(image, &self.options.languages))
96                }
97                #[cfg(target_os = "windows")]
98                {
99                    perform_ocr_windows(image).await
100                }
101                #[cfg(not(any(target_os = "macos", target_os = "windows")))]
102                {
103                    Ok(perform_ocr_tesseract(image, self.options.languages.clone()))
104                }
105            }
106            _ => Err(anyhow::anyhow!("Invalid OCR provider")),
107        }
108    }
109
110    pub async fn recognize_file(&self, path: &str) -> Result<(String, String, Option<f64>)> {
111        let img = image::open(path)?;
112        self.recognize_image(&img).await
113    }
114
115    pub async fn recognize_batch(
116        &self,
117        paths: Vec<&str>,
118    ) -> Result<Vec<(String, String, Option<f64>)>> {
119        let mut results = Vec::with_capacity(paths.len());
120        for path in paths {
121            results.push(self.recognize_file(path).await?);
122        }
123        Ok(results)
124    }
125}
126
127#[cfg(target_os = "macos")]
128pub mod apple;
129pub mod custom_ocr;
130pub mod language;
131#[cfg(target_os = "windows")]
132pub mod microsoft;
133pub mod tesseract;
134
135#[cfg(target_os = "macos")]
136pub use apple::perform_ocr_apple;
137pub use custom_ocr::perform_ocr_custom;
138pub use language::*;
139#[cfg(target_os = "windows")]
140pub use microsoft::perform_ocr_windows;
141pub use tesseract::perform_ocr_tesseract;