Skip to content

Instantly share code, notes, and snippets.

@bczhc
Created March 15, 2026 04:57
Show Gist options
  • Select an option

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

Select an option

Save bczhc/a67f5ef7b8a6d33626899e773fadb4e3 to your computer and use it in GitHub Desktop.
读PNG textual info,用于替代exiftool -Comment -s3。 #image #png
#![feature(file_buffered)]
use clap::Parser;
use serde::Serialize;
use std::fs::File;
use std::path::{Path, PathBuf};
#[derive(Parser)]
struct Args {
path: PathBuf,
}
fn main() -> anyhow::Result<()> {
let args = Args::parse();
let info = read_png_textual_info(&args.path)?;
let json = serde_json::to_string(&info).unwrap();
println!("{}", json);
Ok(())
}
#[derive(Serialize)]
struct TextualEntry {
keyword: String,
text: String,
}
fn read_png_textual_info(path: impl AsRef<Path>) -> anyhow::Result<Vec<TextualEntry>> {
let mut entries = Vec::new();
let png = png::Decoder::new(File::open_buffered(path)?);
let reader = png.read_info()?;
let info = reader.info();
for x in info.uncompressed_latin1_text.clone() {
entries.push(TextualEntry {
keyword: x.keyword,
text: x.text,
});
}
for x in &info.utf8_text {
entries.push(TextualEntry {
keyword: x.keyword.clone(),
text: x.get_text()?.clone(),
});
}
Ok(entries)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment