Skip to content

Commit

Permalink
Merge pull request #4 from demarches-simplifiees/read_from_png_and_pdf
Browse files Browse the repository at this point in the history
Read from png and pdf
  • Loading branch information
LeSim authored Feb 12, 2024
2 parents 19d7b79 + 18a67e1 commit 66a85da
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,9 @@ jobs:
- name: Cache Dependencies
uses: Swatinem/rust-cache@v2

- name: install poppler
run: |
sudo apt-get update
sudo apt-get install -y poppler-utils
- run: cargo test --all-features
66 changes: 65 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ chrono = "*"
p256 = "*"
x509-cert = "*"
base32 = "*"
image = "*"
tempfile = "*"
49 changes: 30 additions & 19 deletions src/datamatrix.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
use rxing::{BarcodeFormat, DecodeHintType, DecodeHintValue, DecodingHintDictionary};

pub fn fetch_datamatrix(file_name: &str) -> Option<String> {
let mut hints = DecodingHintDictionary::from([(
DecodeHintType::TRY_HARDER,
DecodeHintValue::TryHarder(true),
)]);

rxing::helpers::detect_in_file_with_hints(
file_name,
Some(BarcodeFormat::DATA_MATRIX),
&mut hints,
)
.ok()
.map(|res| res.getText().to_string())
use std::collections::HashSet;

use image::DynamicImage;
use rxing::{
common::HybridBinarizer, BarcodeFormat, BinaryBitmap, BufferedImageLuminanceSource,
DecodeHintType, DecodeHintValue, DecodingHintDictionary, MultiFormatReader, Reader,
};

pub fn fetch_datamatrix(img: DynamicImage) -> Option<String> {
let mut multi_format_reader = MultiFormatReader::default();

let hints = DecodingHintDictionary::from([
(DecodeHintType::TRY_HARDER, DecodeHintValue::TryHarder(true)),
(
DecodeHintType::POSSIBLE_FORMATS,
DecodeHintValue::PossibleFormats(HashSet::from([BarcodeFormat::DATA_MATRIX])),
),
]);

let result = multi_format_reader
.decode_with_hints(
&mut BinaryBitmap::new(HybridBinarizer::new(BufferedImageLuminanceSource::new(img))),
&hints,
)
.ok()?;

Some(result.getText().to_string())
}

#[cfg(test)]
Expand All @@ -23,9 +35,8 @@ mod tests {
fn test_fetch_datamatrix() {
let result = "DC02FR000001125E125C0026FR245700010MLLE/SAMPLE/ANGELA\u{1d}20\u{1d}21BAT 2 ETG 3\u{1d}23\u{1d}25METZ\u{1d}227 PLACE DES SPECIMENS\u{1d}\u{1f}Z2HSK7UZM6KPL7UL6OK7NR77GSPGPNNUYYEE4ZV75L5OCIWKVOXTV3I5AJLRSUDOIR76F75QY5Z7KLH3FACKHVF7JH3DYMRI5EIAZMI";

assert_eq!(
fetch_datamatrix("tests/fixtures/2ddoc/justificatif_de_domicile.png"),
Some(result.to_string())
);
let img = image::open("tests/fixtures/2ddoc/justificatif_de_domicile.png").unwrap();

assert_eq!(fetch_datamatrix(img), Some(result.to_string()));
}
}
54 changes: 54 additions & 0 deletions src/file_utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use image::DynamicImage;
use std::process::Command;
use tempfile::Builder;

pub fn file_to_img(file_name: &str) -> DynamicImage {
if file_name.ends_with(".pdf") {
pdf_to_img(file_name)
} else {
image::open(file_name).expect("Failed to open file")
}
}

fn pdf_to_img(file_name: &str) -> DynamicImage {
let temp_file = Builder::new()
.suffix(".png")
.tempfile()
.expect("Failed to create temp file");

let path_without = temp_file.path().with_extension("");
let temp_file_without_extension = path_without.to_str().unwrap();

let status = Command::new("pdftoppm")
.args([
"-png",
"-singlefile",
file_name,
temp_file_without_extension,
])
.status()
.expect("failed to execute process");

assert!(status.success(), "pdftoppm command failed");

image::io::Reader::open(temp_file.path())
.expect("Failed to open temp file")
.decode()
.expect("Failed to decode image")
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_file_to_img() {
let img_from_pdf = file_to_img("tests/fixtures/2ddoc/justificatif_de_domicile.pdf");
assert_eq!(img_from_pdf.width(), 1241);
assert_eq!(img_from_pdf.height(), 1754);

let img_from_png = file_to_img("tests/fixtures/2ddoc/justificatif_de_domicile.png");
assert_eq!(img_from_png.width(), 119);
assert_eq!(img_from_png.height(), 122);
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod datamatrix;
pub mod file_utils;
pub mod twoddoc;
17 changes: 15 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
use la_taupe::{datamatrix::fetch_datamatrix, twoddoc::parse};
use std::env::args;

use la_taupe::{datamatrix::fetch_datamatrix, file_utils::file_to_img, twoddoc::parse};

fn main() {
let datamatrix = fetch_datamatrix("tests/fixtures/2ddoc/justificatif_de_domicile.png");
let args: Vec<String> = args().collect();

if args.len() < 2 {
eprintln!("Usage: {} <path_to_file>", args[0]);
std::process::exit(1);
}

let file_path = &args[1];

let img = file_to_img(file_path);

let datamatrix = fetch_datamatrix(img);

if let Some(datamatrix) = datamatrix {
let ddoc = parse(&datamatrix);
Expand Down
Binary file added tests/fixtures/2ddoc/justificatif_de_domicile.pdf
Binary file not shown.

0 comments on commit 66a85da

Please sign in to comment.