pub struct Reader { /* private fields */ }
Expand description
A struct to parse the Exif attributes and
create an Exif
instance that holds the results.
§Examples
use exif::{In, Reader, Tag};
let file = std::fs::File::open("tests/exif.jpg")?;
let exif = Reader::new()
.read_from_container(&mut std::io::BufReader::new(&file))?;
let xres = exif.get_field(Tag::XResolution, In::PRIMARY)
.ok_or(Error("tests/exif.jpg must have XResolution"))?;
assert_eq!(xres.display_value().with_unit(&exif).to_string(),
"72 pixels per inch");
Implementations§
Source§impl Reader
impl Reader
Sourcepub fn new() -> Self
pub fn new() -> Self
Constructs a new Reader
.
Examples found in repository?
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
fn dump_file(path: &Path) -> Result<(), exif::Error> {
let file = File::open(path)?;
// To parse strictly:
// let exif = exif::Reader::new()
// .read_from_container(&mut BufReader::new(&file))?;
// To parse with continue-on-error mode:
let exif = exif::Reader::new()
.continue_on_error(true)
.read_from_container(&mut BufReader::new(&file))
.or_else(|e| e.distill_partial_result(|errors| {
eprintln!("{}: {} warning(s)", path.display(), errors.len());
errors.iter().for_each(|e| eprintln!(" {}", e));
}))?;
println!("{}", path.display());
for f in exif.fields() {
println!(" {}/{}: {}",
f.ifd_num.index(), f.tag,
f.display_value().with_unit(&exif));
println!(" {:?}", f.value);
}
Ok(())
}
More examples
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
fn main() {
let file = File::open("tests/exif.jpg").unwrap();
let exif = Reader::new().read_from_container(
&mut BufReader::new(&file)).unwrap();
// To obtain a string representation, `Value::display_as`
// or `Field::display_value` can be used. To display a value with its
// unit, call `with_unit` on the return value of `Field::display_value`.
let tag_list = [Tag::ExifVersion,
Tag::PixelXDimension,
Tag::XResolution,
Tag::ImageDescription,
Tag::DateTime];
for tag in tag_list {
if let Some(field) = exif.get_field(tag, In::PRIMARY) {
println!("{}: {}",
field.tag, field.display_value().with_unit(&exif));
}
}
// To get unsigned integer value(s) from either of BYTE, SHORT,
// or LONG, `Value::get_uint` or `Value::iter_uint` can be used.
if let Some(field) = exif.get_field(Tag::PixelXDimension, In::PRIMARY) {
if let Some(width) = field.value.get_uint(0) {
println!("Valid width of the image is {}.", width);
}
}
// To convert a Rational or SRational to an f64, `Rational::to_f64`
// or `SRational::to_f64` can be used.
if let Some(field) = exif.get_field(Tag::XResolution, In::PRIMARY) {
match field.value {
Value::Rational(ref vec) if !vec.is_empty() =>
println!("X resolution is {}.", vec[0].to_f64()),
_ => {},
}
}
// To parse a DateTime-like field, `DateTime::from_ascii` can be used.
if let Some(field) = exif.get_field(Tag::DateTime, In::PRIMARY) {
match field.value {
Value::Ascii(ref vec) if !vec.is_empty() => {
if let Ok(datetime) = DateTime::from_ascii(&vec[0]) {
println!("Year of DateTime is {}.", datetime.year);
}
},
_ => {},
}
}
}
Sourcepub fn continue_on_error(&mut self, continue_on_error: bool) -> &mut Self
pub fn continue_on_error(&mut self, continue_on_error: bool) -> &mut Self
Sets the option to continue parsing on non-fatal errors.
When this option is enabled, the parser will not stop on non-fatal
errors and returns the results as far as they can be parsed.
In such a case, read_raw
and read_from_container
return Error::PartialResult
.
The partial result and ignored errors can be obtained by
Error::distill_partial_result
or PartialResult::into_inner
.
Note that a hard error (other than Error::PartialResult
) may be
returned even if this option is enabled.
§Examples
use exif::Reader;
let file = std::fs::File::open("tests/exif.jpg")?;
let exif = Reader::new()
.continue_on_error(true)
.read_from_container(&mut std::io::BufReader::new(&file))
.or_else(|e| e.distill_partial_result(|errors| {
errors.iter().for_each(|e| eprintln!("Warning: {}", e));
}))?;
Examples found in repository?
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
fn dump_file(path: &Path) -> Result<(), exif::Error> {
let file = File::open(path)?;
// To parse strictly:
// let exif = exif::Reader::new()
// .read_from_container(&mut BufReader::new(&file))?;
// To parse with continue-on-error mode:
let exif = exif::Reader::new()
.continue_on_error(true)
.read_from_container(&mut BufReader::new(&file))
.or_else(|e| e.distill_partial_result(|errors| {
eprintln!("{}: {} warning(s)", path.display(), errors.len());
errors.iter().for_each(|e| eprintln!(" {}", e));
}))?;
println!("{}", path.display());
for f in exif.fields() {
println!(" {}/{}: {}",
f.ifd_num.index(), f.tag,
f.display_value().with_unit(&exif));
println!(" {:?}", f.value);
}
Ok(())
}
Sourcepub fn read_raw(&self, data: Vec<u8>) -> Result<Exif, Error>
pub fn read_raw(&self, data: Vec<u8>) -> Result<Exif, Error>
Parses the Exif attributes from raw Exif data.
If an error occurred, exif::Error
is returned.
Sourcepub fn read_from_container<R>(&self, reader: &mut R) -> Result<Exif, Error>
pub fn read_from_container<R>(&self, reader: &mut R) -> Result<Exif, Error>
Reads an image file and parses the Exif attributes in it.
If an error occurred, exif::Error
is returned.
Supported formats are:
- TIFF and some RAW image formats based on it
- JPEG
- HEIF and coding-specific variations including HEIC and AVIF
- PNG
- WebP
This method is provided for the convenience even though parsing containers is basically out of the scope of this library.
Examples found in repository?
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
fn dump_file(path: &Path) -> Result<(), exif::Error> {
let file = File::open(path)?;
// To parse strictly:
// let exif = exif::Reader::new()
// .read_from_container(&mut BufReader::new(&file))?;
// To parse with continue-on-error mode:
let exif = exif::Reader::new()
.continue_on_error(true)
.read_from_container(&mut BufReader::new(&file))
.or_else(|e| e.distill_partial_result(|errors| {
eprintln!("{}: {} warning(s)", path.display(), errors.len());
errors.iter().for_each(|e| eprintln!(" {}", e));
}))?;
println!("{}", path.display());
for f in exif.fields() {
println!(" {}/{}: {}",
f.ifd_num.index(), f.tag,
f.display_value().with_unit(&exif));
println!(" {:?}", f.value);
}
Ok(())
}
More examples
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
fn main() {
let file = File::open("tests/exif.jpg").unwrap();
let exif = Reader::new().read_from_container(
&mut BufReader::new(&file)).unwrap();
// To obtain a string representation, `Value::display_as`
// or `Field::display_value` can be used. To display a value with its
// unit, call `with_unit` on the return value of `Field::display_value`.
let tag_list = [Tag::ExifVersion,
Tag::PixelXDimension,
Tag::XResolution,
Tag::ImageDescription,
Tag::DateTime];
for tag in tag_list {
if let Some(field) = exif.get_field(tag, In::PRIMARY) {
println!("{}: {}",
field.tag, field.display_value().with_unit(&exif));
}
}
// To get unsigned integer value(s) from either of BYTE, SHORT,
// or LONG, `Value::get_uint` or `Value::iter_uint` can be used.
if let Some(field) = exif.get_field(Tag::PixelXDimension, In::PRIMARY) {
if let Some(width) = field.value.get_uint(0) {
println!("Valid width of the image is {}.", width);
}
}
// To convert a Rational or SRational to an f64, `Rational::to_f64`
// or `SRational::to_f64` can be used.
if let Some(field) = exif.get_field(Tag::XResolution, In::PRIMARY) {
match field.value {
Value::Rational(ref vec) if !vec.is_empty() =>
println!("X resolution is {}.", vec[0].to_f64()),
_ => {},
}
}
// To parse a DateTime-like field, `DateTime::from_ascii` can be used.
if let Some(field) = exif.get_field(Tag::DateTime, In::PRIMARY) {
match field.value {
Value::Ascii(ref vec) if !vec.is_empty() => {
if let Ok(datetime) = DateTime::from_ascii(&vec[0]) {
println!("Year of DateTime is {}.", datetime.year);
}
},
_ => {},
}
}
}