X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=mediagoblin%2Ftools%2Fexif.py;h=fafd987d167680e267b893ab663edd7aa75f23d8;hb=db6cc0c0613f324b062e2c396fec6f26c504e362;hp=ab3f77f0377ce1ffb3745b2b04574e9846aeaefa;hpb=591c11609852c5481f00bf0eaa01ceafcd244f38;p=mediagoblin.git diff --git a/mediagoblin/tools/exif.py b/mediagoblin/tools/exif.py index ab3f77f0..fafd987d 100644 --- a/mediagoblin/tools/exif.py +++ b/mediagoblin/tools/exif.py @@ -14,10 +14,10 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -try: - from EXIF import process_file, Ratio -except ImportError: - from mediagoblin.tools.extlib.EXIF import process_file, Ratio +import six + +from exifread import process_file +from exifread.utils import Ratio from mediagoblin.processing import BadMediaFail from mediagoblin.tools.translate import pass_to_ugettext as _ @@ -50,7 +50,10 @@ def exif_fix_image_orientation(im, exif_tags): Translate any EXIF orientation to raw orientation Cons: - - REDUCES IMAGE QUALITY by recompressig it + - Well, it changes the image, which means we'll recompress + it... not a problem if scaling it down already anyway. We might + lose some quality in recompressing if it's at the same-size + though Pros: - Prevents neck pain @@ -62,7 +65,7 @@ def exif_fix_image_orientation(im, exif_tags): 6: 270, 8: 90} orientation = exif_tags['Image Orientation'].values[0] - if orientation in rotation_map.keys(): + if orientation in rotation_map: im = im.rotate( rotation_map[orientation]) @@ -73,16 +76,12 @@ def extract_exif(filename): """ Returns EXIF tags found in file at ``filename`` """ - exif_tags = {} - try: - image = open(filename) - exif_tags = process_file(image, details=False) + with open(filename, 'rb') as image: + return process_file(image, details=False) except IOError: raise BadMediaFail(_('Could not read the image file.')) - return exif_tags - def clean_exif(exif): ''' @@ -96,12 +95,8 @@ def clean_exif(exif): 'JPEGThumbnail', 'Thumbnail JPEGInterchangeFormat'] - clean_exif = {} - - for key, value in exif.items(): - if not key in disabled_tags: - clean_exif[key] = _ifd_tag_to_dict(value) - return clean_exif + return dict((key, _ifd_tag_to_dict(value)) for (key, value) + in six.iteritems(exif) if key not in disabled_tags) def _ifd_tag_to_dict(tag): @@ -117,20 +112,15 @@ def _ifd_tag_to_dict(tag): 'field_length': tag.field_length, 'values': None} - if isinstance(tag.printable, str): + if isinstance(tag.printable, six.binary_type): # Force it to be decoded as UTF-8 so that it'll fit into the DB data['printable'] = tag.printable.decode('utf8', 'replace') if type(tag.values) == list: - data['values'] = [] - for val in tag.values: - if isinstance(val, Ratio): - data['values'].append( - _ratio_to_list(val)) - else: - data['values'].append(val) + data['values'] = [_ratio_to_list(val) if isinstance(val, Ratio) else val + for val in tag.values] else: - if isinstance(tag.values, str): + if isinstance(tag.values, six.binary_type): # Force UTF-8, so that it fits into the DB data['values'] = tag.values.decode('utf8', 'replace') else: @@ -144,18 +134,19 @@ def _ratio_to_list(ratio): def get_useful(tags): - useful = {} - for key, tag in tags.items(): - if key in USEFUL_TAGS: - useful[key] = tag - - return useful + from collections import OrderedDict + return OrderedDict((key, tag) for (key, tag) in six.iteritems(tags)) def get_gps_data(tags): """ Processes EXIF data returned by EXIF.py """ + def safe_gps_ratio_divide(ratio): + if ratio.den == 0: + return 0.0 + return float(ratio.num) / float(ratio.den) + gps_data = {} if not 'Image GPSInfo' in tags: @@ -166,12 +157,12 @@ def get_gps_data(tags): 'latitude': tags['GPS GPSLatitude'], 'longitude': tags['GPS GPSLongitude']} - for key, dat in dms_data.items(): + for key, dat in six.iteritems(dms_data): gps_data[key] = ( lambda v: - float(v[0].num) / float(v[0].den) \ - + (float(v[1].num) / float(v[1].den) / 60) \ - + (float(v[2].num) / float(v[2].den) / (60 * 60)) + safe_gps_ratio_divide(v[0]) \ + + (safe_gps_ratio_divide(v[1]) / 60) \ + + (safe_gps_ratio_divide(v[2]) / (60 * 60)) )(dat.values) if tags['GPS GPSLatitudeRef'].values == 'S':