Skip to content

Instantly share code, notes, and snippets.

@bczhc
Last active December 11, 2025 08:14
Show Gist options
  • Select an option

  • Save bczhc/d588e5acc0972b48d1e5f37074979376 to your computer and use it in GitHub Desktop.

Select an option

Save bczhc/d588e5acc0972b48d1e5f37074979376 to your computer and use it in GitHub Desktop.
高性能快速输出图片ev100值 #photography #image
#!/bin/env rust-script
//! ```cargo
//! [dependencies]
//! rexif = "0.7.5"
//! serde_json = "1.0.145"
//! ```
use std::env;
use rexif::{ExifTag, TagValue};
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
eprintln!("用法: {} <图片路径>", args[0]);
std::process::exit(1);
}
let file_path = &args[1];
let exif_data = match rexif::parse_file(file_path) {
Ok(data) => data,
Err(e) => {
eprintln!("错误: 无法解析文件 '{}'。原因: {}", file_path, e);
std::process::exit(1);
}
};
let mut f_number: Option<f64> = None;
let mut exposure_time: Option<f64> = None;
let mut iso: Option<f64> = None;
for entry in exif_data.entries {
match entry.tag {
ExifTag::FNumber => {
if let TagValue::URational(ref v) = entry.value {
if !v.is_empty() {
f_number = Some(v[0].numerator as f64 / v[0].denominator as f64);
}
}
}
ExifTag::ExposureTime => {
if let TagValue::URational(ref v) = entry.value {
if !v.is_empty() {
exposure_time = Some(v[0].numerator as f64 / v[0].denominator as f64);
}
}
}
ExifTag::ISOSpeedRatings => {
match entry.value {
TagValue::U16(ref v) if !v.is_empty() => iso = Some(v[0] as f64),
_ => {}
}
}
_ => {}
}
}
if let (Some(n), Some(t), Some(s)) = (f_number, exposure_time, iso) {
let ev_current = (n.powi(2) / t).log2();
let ev100 = ev_current - (s / 100.0).log2();
let obj = serde_json::json!({
"ev100": ev100,
"path": file_path
});
println!("{}", obj);
} else {
eprintln!("错误: 图片缺少必要的 EXIF 数据 (光圈、快门或 ISO)。");
std::process::exit(1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment