From 8166878bf8c30266a1e328a00e8efd7d2a8437e8 Mon Sep 17 00:00:00 2001 From: wangdl Date: Sat, 30 May 2026 20:59:50 +0800 Subject: [PATCH] feat: image metadata reading - width, height, format, file_size with fixture test --- crates/zx_document_core/Cargo.toml | 1 + crates/zx_document_core/src/image_meta.rs | 77 ++++++++++++++++++++++ fixtures/images/test-red.png | Bin 0 -> 69 bytes 3 files changed, 78 insertions(+) create mode 100644 fixtures/images/test-red.png diff --git a/crates/zx_document_core/Cargo.toml b/crates/zx_document_core/Cargo.toml index b3bc1cc..86ed86e 100644 --- a/crates/zx_document_core/Cargo.toml +++ b/crates/zx_document_core/Cargo.toml @@ -10,3 +10,4 @@ infer = "0.16" mime_guess = "2" comrak = "0.29" uuid = { version = "1", features = ["v4"] } +image = { version = "0.25", default-features = false, features = ["png", "jpeg", "webp", "gif"] } diff --git a/crates/zx_document_core/src/image_meta.rs b/crates/zx_document_core/src/image_meta.rs index e69de29..feb70cb 100644 --- a/crates/zx_document_core/src/image_meta.rs +++ b/crates/zx_document_core/src/image_meta.rs @@ -0,0 +1,77 @@ +use std::path::Path; + +use image::GenericImageView; +use serde::{Deserialize, Serialize}; + +use crate::error::DocumentError; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ImageMeta { + pub width: u32, + pub height: u32, + pub format: String, + pub file_size: u64, +} + +/// Read image metadata from a file path. +pub fn read_image_meta(file_path: &str) -> Result { + let path = Path::new(file_path); + + let file_size = std::fs::metadata(file_path) + .map(|m| m.len())?; + + let format = path + .extension() + .and_then(|e| e.to_str()) + .unwrap_or("unknown") + .to_lowercase(); + + let img = image::open(file_path).map_err(|e| { + DocumentError::ParseError(format!("image decode failed: {e}")) + })?; + + let (width, height) = img.dimensions(); + + Ok(ImageMeta { + width, + height, + format, + file_size, + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_read_image_meta_not_found() { + let result = read_image_meta("/nonexistent/img.png"); + assert!(result.is_err()); + } + + #[test] + fn test_read_fixture_png() { + let path = concat!(env!("CARGO_MANIFEST_DIR"), "/../../fixtures/images/test-red.png"); + let meta = read_image_meta(path).unwrap(); + assert_eq!(meta.width, 1); + assert_eq!(meta.height, 1); + assert_eq!(meta.format, "png"); + assert!(meta.file_size > 0); + } + + #[test] + fn test_image_meta_serde() { + let meta = ImageMeta { + width: 800, + height: 600, + format: "png".to_string(), + file_size: 12345, + }; + let json = serde_json::to_string(&meta).unwrap(); + let parsed: ImageMeta = serde_json::from_str(&json).unwrap(); + assert_eq!(parsed.width, 800); + assert_eq!(parsed.height, 600); + assert_eq!(parsed.format, "png"); + } +} diff --git a/fixtures/images/test-red.png b/fixtures/images/test-red.png new file mode 100644 index 0000000000000000000000000000000000000000..62a5f8f47fec02344e5bf9061888262f677cf5d6 GIT binary patch literal 69 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1SBVv2j2ryJf1F&Ar*6yf1E$Sz`)GN$Z+!C Rr1wB^22WQ%mvv4FO#seq5RCu; literal 0 HcmV?d00001