hMatoba / Piexif

Exif manipulation with pure python script.
MIT License
369 stars 82 forks source link

Differentiating between binary blobs and strings #58

Open sjlongland opened 6 years ago

sjlongland commented 6 years ago

Hi,

I recently stumbled on this looking for a way to parse EXIF in a photo gallery app. I'm using Tornado on Python 3.5, but hit a stumbling block in that the EXIF library gives me text as binary strings; I can't tell which are binary blobs and which are actual strings for me to decode.

As an example, take this photo: http://gallery.longlandclan.id.au/raw/snowys-2018/20180415-dscf7010.jpg

piexif gives me this:

In [5]: piexif.load('20180415-dscf7010.jpg', True)
Out[5]: 
{'0th': {'Copyright': b'    ',
  'DateTime': b'2018:04:15 09:20:09',
  'ExifTag': 300,
  'Make': b'FUJIFILM',
  'Model': b'FinePix S1000fd   ',
  'Orientation': 1,
  'PrintImageMatching': b'PrintIM\x000250\x00\x00\x02\x00\x02\x00\x01\x00\x00\x00\x01\x01\x00\x00\x00\x00',
  'ResolutionUnit': 2,
  'Software': b'Digital Camera FinePix S1000fd Ver1.03   ',
  'XResolution': (72, 1),
  'YCbCrPositioning': 2,
  'YResolution': (72, 1)},
 '1st': {'Compression': 6,
  'JPEGInterchangeFormat': 1880,
  'JPEGInterchangeFormatLength': 8958,
  'Orientation': 1,
  'ResolutionUnit': 2,
  'XResolution': (72, 1),
  'YCbCrPositioning': 2,
  'YResolution': (72, 1)},
 'Exif': {'ApertureValue': (400, 100),
  'BrightnessValue': (500, 100),
  'ColorSpace': 1,
  'ComponentsConfiguration': b'\x01\x02\x03\x00',
  'CompressedBitsPerPixel': (40, 10),
  'CustomRendered': 0,
  'DateTimeDigitized': b'2018:04:15 09:20:09',
  'DateTimeOriginal': b'2018:04:15 09:20:09',
  'ExifVersion': b'0220',
  'ExposureBiasValue': (0, 100),
  'ExposureMode': 0,
  'ExposureProgram': 3,
  'ExposureTime': (10, 1200),
  'FNumber': (400, 100),
  'FileSource': b'\x03',
  'Flash': 16,
  'FlashpixVersion': b'0100',
  'FocalLength': (59, 10),
  'FocalPlaneResolutionUnit': 3,
  'FocalPlaneXResolution': (6129, 1),
  'FocalPlaneYResolution': (6129, 1),
  'ISOSpeedRatings': 64,
  'InteroperabilityTag': 1732,
  'LightSource': 0,
  'MakerNote': b'FUJIFILM\x0c\x00\x00\x00 \x00\x00\x00\x07\x00\x04\x00\x00\x000130\x10\x00\x02\x00\x1f\x00\x00\x00\n\x02\x00\x00\x00\x10\x02\x00\x08\x00\x00\x00*\x02\x00\x00\x01\x10\x03\x00\x01\x00\x00\x00\x04\x00\x00\x00\x02\x10\x03\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x10\x03\x00\x01\x00\x00\x00\x00\x00\x00\x00\x10\x10\x03\x00…

Some of these are clearly human-readable text, but MakerNote for example, most definitely is not text. Both are represented with bytes. I'd like to emit this data as JSON, however json.dumps takes great umbrage to the fact that I'm handing it bytes objects. Is there a flag somewhere I can set that will decode the byte strings representing text into str objects?

sjlongland commented 6 years ago

For the record, this is the work-around I'm using:

https://github.com/sjlongland/tornado-gallery/commit/a6d6a58acdc0ddbcac9a1f67a097ebd1647d68f0

That gives the following: http://gallery.longlandclan.id.au/meta/snowys-2018/20180415-dscf7010.jpg