I think this is the same old bug that you fixed before and should rear it's head on any of those previously submitted Nikon images that have binary or unicode in the the UserComment string. I've attached one that I used to duplicate it this morning on the latest pyexiv2 for precise pangolin ('0.3.2').
To duplicate, run this following function on an image instance that has been loaded and read by pexiv2 (or you can clone tagim from <email address hidden>:hobsonlane/tagim.git and do `tagim -i 'DSCN2162.JPG' --debug` ....
def display_meta_str(im):
keysets = {'EXIF':im.exif_keys, 'IPTC':im.iptc_keys, ' XMP':im.xmp_keys}
for name,keys in keysets.items():
title = ' %s Data '%name
print '-'*30 + title + '-'*30
for k in keys:
print u'{0}: {1}'.format(str(k),str(im[k].value))
print '-'*(60+len(title))
print '-'*30 + ' Comment '+'-'*30
print im.comment
print '-'*(60+len(title))
return keysets.values()
Here's the output for this particular image (with error message at end):
Image file name: 'DSCN2161.JPG'
------------------------------ IPTC Data ------------------------------
-----------------------------------------------------------------------
------------------------------ XMP Data ------------------------------
-----------------------------------------------------------------------
------------------------------ EXIF Data ------------------------------
Exif.Image.ImageDescription:
Exif.Image.Make: NIKON
Exif.Image.Model: COOLPIX L18
Exif.Image.Orientation: 1
Exif.Image.XResolution: 300
Exif.Image.YResolution: 300
Exif.Image.ResolutionUnit: 2
Exif.Image.Software: COOLPIX L18 V1.1
Exif.Image.DateTime: 2009-07-23 22:04:56
Exif.Image.YCbCrPositioning: 2
Exif.Image.ExifTag: 230
Exif.Photo.ExposureTime: 1/60
Exif.Photo.FNumber: 14/5
Exif.Photo.ExposureProgram: 2
Exif.Photo.ISOSpeedRatings: 565
Exif.Photo.ExifVersion: 0220
Exif.Photo.DateTimeOriginal: 2009-07-23 22:04:56
Exif.Photo.DateTimeDigitized: 2009-07-23 22:04:56
Exif.Photo.ComponentsConfiguration:
Exif.Photo.CompressedBitsPerPixel: 2
Exif.Photo.ExposureBiasValue: 0
Exif.Photo.MaxApertureValue: 3
Exif.Photo.MeteringMode: 5
Exif.Photo.LightSource: 0
Exif.Photo.Flash: 25
Exif.Photo.FocalLength: 57/10
Traceback (most recent call last):
File "/home/hobs/bin/tagim", line 346, in <module>
tagim.display_meta_str(im)
File "/home/hobs/src/tagim/tg/tagim.py", line 212, in display_meta_str
print u'{0}: {1}'.format(str(k),str(im[k].value))
UnicodeDecodeError: 'ascii' codec can't decode byte 0x8e in position 52: ordinal not in range(128)
And here's the workaround -- use unicode() instead of str()):
print u'{0}: {1}'.format(unicode_noerr(k),unicode_noerr(im[k].value, errors='replace'))
def unicode_noerr(s,errors='replace'):
"""
Coerce input into a unicode (multibyte) string regardless of the type of input, without raising exceptions.
Assumes any single-byte str is UTF-8 or ASCII.
"""
if type(s)==unicode: return s
elif type(s)==str: return s.decode('UTF-8',errors=errors)
else: return unicode(s)
I think this is the same old bug that you fixed before and should rear it's head on any of those previously submitted Nikon images that have binary or unicode in the the UserComment string. I've attached one that I used to duplicate it this morning on the latest pyexiv2 for precise pangolin ('0.3.2').
To duplicate, run this following function on an image instance that has been loaded and read by pexiv2 (or you can clone tagim from <email address hidden> :hobsonlane/ tagim.git and do `tagim -i 'DSCN2162.JPG' --debug` ....
def display_ meta_str( im): :im.exif_ keys, 'IPTC': im.iptc_ keys, ' XMP':im.xmp_keys} str(k), str(im[ k].value) )
keysets = {'EXIF'
for name,keys in keysets.items():
title = ' %s Data '%name
print '-'*30 + title + '-'*30
for k in keys:
print u'{0}: {1}'.format(
print '-'*(60+len(title))
print '-'*30 + ' Comment '+'-'*30
print im.comment
print '-'*(60+len(title))
return keysets.values()
Here's the output for this particular image (with error message at end):
Image file name: 'DSCN2161.JPG' ------- ------- ------- -- IPTC Data ------- ------- ------- ------- -- ------- ------- ------- ------- ------- ------- ------- ------- ------- - ------- ------- ------- -- XMP Data ------- ------- ------- ------- -- ------- ------- ------- ------- ------- ------- ------- ------- ------- - ------- ------- ------- -- EXIF Data ------- ------- ------- ------- -- ImageDescriptio n: Orientation: 1 XResolution: 300 YResolution: 300 ResolutionUnit: 2 Software: COOLPIX L18 V1.1 DateTime: 2009-07-23 22:04:56 YCbCrPositionin g: 2 ExposureTime: 1/60 ExposureProgram : 2 ISOSpeedRatings : 565 ExifVersion: 0220 DateTimeOrigina l: 2009-07-23 22:04:56 DateTimeDigitiz ed: 2009-07-23 22:04:56 ComponentsConfi guration: CompressedBitsP erPixel: 2 ExposureBiasVal ue: 0 MaxApertureValu e: 3 MeteringMode: 5 LightSource: 0 FocalLength: 57/10 hobs/bin/ tagim", line 346, in <module> display_ meta_str( im) hobs/src/ tagim/tg/ tagim.py" , line 212, in display_meta_str str(k), str(im[ k].value) )
-------
-------
-------
-------
-------
Exif.Image.
Exif.Image.Make: NIKON
Exif.Image.Model: COOLPIX L18
Exif.Image.
Exif.Image.
Exif.Image.
Exif.Image.
Exif.Image.
Exif.Image.
Exif.Image.
Exif.Image.ExifTag: 230
Exif.Photo.
Exif.Photo.FNumber: 14/5
Exif.Photo.
Exif.Photo.
Exif.Photo.
Exif.Photo.
Exif.Photo.
Exif.Photo.
Exif.Photo.
Exif.Photo.
Exif.Photo.
Exif.Photo.
Exif.Photo.
Exif.Photo.Flash: 25
Exif.Photo.
Traceback (most recent call last):
File "/home/
tagim.
File "/home/
print u'{0}: {1}'.format(
UnicodeDecodeError: 'ascii' codec can't decode byte 0x8e in position 52: ordinal not in range(128)
And here's the workaround -- use unicode() instead of str()):
print u'{0}: {1}'.format( unicode_ noerr(k) ,unicode_ noerr(im[ k].value, errors='replace')) noerr(s, errors= 'replace' ):
def unicode_
"""
Coerce input into a unicode (multibyte) string regardless of the type of input, without raising exceptions.
Assumes any single-byte str is UTF-8 or ASCII. 'UTF-8' ,errors= errors)
"""
if type(s)==unicode: return s
elif type(s)==str: return s.decode(
else: return unicode(s)
Or run tagim without the `--debug` flag.