On OS X, read Exif tags using Cocoa's built-in functionality

This allows for RAW files Exif reading. Fixes #234.
This commit is contained in:
Virgil Dupras 2013-11-10 12:00:16 -05:00
parent 76f45fb5a6
commit 1d9573cf6f
4 changed files with 37 additions and 7 deletions

View File

@ -6,7 +6,6 @@
# which should be included with this package. The terms are also available at
# http://www.hardcoded.net/licenses/bsd_license
import os.path as op
import plistlib
import logging
import re
@ -48,6 +47,16 @@ class Photo(PhotoBase):
raise IOError('The picture %s could not be read' % str(self.path))
return blocks
def _get_exif_timestamp(self):
exifdata = proxy.readExifData_(str(self.path))
if exifdata:
try:
return exifdata['{Exif}']['DateTimeOriginal']
except KeyError:
return ''
else:
return ''
class IPhoto(Photo):
def __init__(self, path, db_id):

View File

@ -30,4 +30,5 @@
- (void)destroyPool;
- (void)reportCrash:(NSString *)crashReport;
- (void)log:(NSString *)s;
- (NSDictionary *)readExifData:(NSString *)imagePath;
@end

View File

@ -157,4 +157,20 @@
{
NSLog(@"%@", s);
}
- (NSDictionary *)readExifData:(NSString *)imagePath
{
NSDictionary *result = nil;
NSURL* url = [NSURL fileURLWithPath:imagePath];
CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url, nil);
if (source != nil) {
CFDictionaryRef metadataRef = CGImageSourceCopyPropertiesAtIndex (source, 0, nil);
if (metadataRef != nil) {
result = [NSDictionary dictionaryWithDictionary:(NSDictionary *)metadataRef];
CFRelease(metadataRef);
}
CFRelease(source);
}
return result;
}
@end

View File

@ -49,6 +49,15 @@ class Photo(fs.File):
self._cached_orientation = 0
return self._cached_orientation
def _get_exif_timestamp(self):
try:
with self.path.open('rb') as fp:
exifdata = exif.get_fields(fp)
return exifdata['DateTimeOriginal']
except Exception:
logging.info("Couldn't read EXIF of picture: %s", self.path)
return ''
@classmethod
def can_handle(cls, path):
return fs.File.can_handle(path) and get_file_ext(path[-1]) in cls.HANDLED_EXTS
@ -89,12 +98,7 @@ class Photo(fs.File):
if self._get_orientation() in {5, 6, 7, 8}:
self.dimensions = (self.dimensions[1], self.dimensions[0])
elif field == 'exif_timestamp':
try:
with self.path.open('rb') as fp:
exifdata = exif.get_fields(fp)
self.exif_timestamp = exifdata['DateTimeOriginal']
except Exception:
logging.info("Couldn't read EXIF of picture: %s", self.path)
self.exif_timestamp = self._get_exif_timestamp()
def get_blocks(self, block_count_per_side):
return self._plat_get_blocks(block_count_per_side, self._get_orientation())