Re: Retrieving the EXIF date/time from 250k images
Re: Retrieving the EXIF date/time from 250k images
- Subject: Re: Retrieving the EXIF date/time from 250k images
- From: "Gary L. Wade via Cocoa-dev" <email@hidden>
- Date: Sun, 14 Aug 2022 18:51:33 -0700
I noticed you release the fileProps but didn’t release the image, but I don’t
know if that’s one of those details you left out for clarity. Also, depending
on some factors like mutability, while the initWithString call with a
CFStringRef might essentially be a no-op, you can just do the typecast on the
dateref and pass it directly into dateFromString.
One thing I’d suggest is to do the work for each image asynchronously on a
background queue and have that block (essentially all of your for-loop code)
report its completion by some asynchronous way like posting a notification on
the original queue along with the result you care about, the parsed date
associated with the particular file. Let the original queue handle how to
store each parsed date; it would probably be best to use a dictionary where the
key was the filename and value is the date. To prevent memory pressure,
allocate your background queue so that it’s concurrent and autorelease
frequency is set to be workItem. If you want to be sure to know when
everything’s done, you could use a DispatchGroup to track those and you could
choose to pass back NSNull or nil for the parsed result if the date could not
be parsed.
Of course, this will depend on if your file system is non-network-based and
whether it’s SSD vs HD as well as other physical system factors.
--
Gary
> On Aug 14, 2022, at 2:22 PM, Gabriel Zachmann via Cocoa-dev
> <email@hidden> wrote:
>
> I would like to collect the date/time stored in an EXIF tag in a bunch of
> images.
>
> I thought I could do so with the following procedure
> (some details and error checking omitted for sake of clarity):
>
>
> NSMutableArray * dates_and_times = [NSMutableArray arrayWithCapacity:
> [imagefiles count]];
> CFDictionaryRef exif_dict;
> CFStringRef dateref = NULL;
> for ( NSString* filename in imagefiles )
> {
> NSURL * imgurl = [NSURL fileURLWithPath: filename isDirectory: NO];
> // escapes any chars that are not allowed in URLs (space, &, etc.)
> CGImageSourceRef image = CGImageSourceCreateWithURL( (__bridge
> CFURLRef) imgurl, NULL );
> CFDictionaryRef fileProps = CGImageSourceCopyPropertiesAtIndex( image,
> 0, NULL );
> bool success = CFDictionaryGetValueIfPresent( fileProps,
> kCGImagePropertyExifDictionary, (const void **) & exif_dict );
> success = CFDictionaryGetValueIfPresent( exif_dict,
> kCGImagePropertyExifDateTimeDigitized, (const void **) & dateref );
> NSString * date_str = [[NSString alloc] initWithString: (__bridge
> NSString * _Nonnull)( dateref ) ];
> NSDate * iso_date = [isoDateFormatter_ dateFromString: date_str];
> if ( iso_date )
> [dates_and_times addObject: iso_date ];
> CFRelease( fileProps );
> }
>
>
> But, I get the impression, this code actually loads each and every image.
> On my Macbook, it takes 3m30s for 250k images (130GB).
>
> So, the big question is: can it be done faster?
>
> I know the EXIF tags are part of the image file, but I was hoping it might be
> possible to load only those EXIF dictionaries.
> Or are the CGImage functions above already clever enough to implement this
> idea?
>
>
> Best regards, Gab.
>
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden