exif

Struct Reader

Source
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

Source

pub fn new() -> Self

Constructs a new Reader.

Examples found in repository?
examples/dumpexif.rs (line 50)
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
Hide additional examples
examples/reading.rs (line 36)
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);
                }
            },
            _ => {},
        }
    }
}
Source

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?
examples/dumpexif.rs (line 51)
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(())
}
Source

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.

Source

pub fn read_from_container<R>(&self, reader: &mut R) -> Result<Exif, Error>
where R: BufRead + Seek,

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?
examples/dumpexif.rs (line 52)
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
Hide additional examples
examples/reading.rs (lines 36-37)
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);
                }
            },
            _ => {},
        }
    }
}

Auto Trait Implementations§

§

impl Freeze for Reader

§

impl RefUnwindSafe for Reader

§

impl Send for Reader

§

impl Sync for Reader

§

impl Unpin for Reader

§

impl UnwindSafe for Reader

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.