| Cocoa EXIF rotation |
[Sat, 27-Dec-2008 3:38 PM] |
Dear Lazyweb, How do you load an NSImage with proper EXIF rotation applied? I can't figure out how to determine the correct rotation. The following doesn't work. I get a dictionary containing a bunch of EXIF keys like exposure and shutter speed, but the "Orientation" tag is notably missing, and the image is displayed sideways. Preview and Finder display it properly, and exiftool says the field is there.
NSImage *img = [[NSImage alloc] initWithContentsOfFile:filename];
NSArray *reps = [img representations];
NSBitmapImageRep *rep = reps ? [reps objectAtIndex:0] : 0;
if (rep) {
NSDictionary *exif = [rep valueForProperty: @"NSImageEXIFData"];
if (exif) {
NSString *rot = [exif objectForKey:@"Orientation"];
NSLog (@"rot = %@", rot);
NSEnumerator *e = [exif keyEnumerator];
id key;
while ((key = [e nextObject])) {
NSLog (@"%@ = %@", key, [exif objectForKey:key]);
}
}
} |
|
|
| Comments: |
I have to say it's creepy that when i google "NSImageEXIFData Orientation", this is the first result.
![[User Picture]](http://l-userpic.livejournal.com/142571/28061) | From: poon Sun, 28-Dec-2008 12:21 AM (UTC)
Using libexif | (Link)
|
Cocoa provides no love.
Using libexif from http://sf.net/projects/libexif :
#include <stdio.h>
#include <stdlib.h>
#include <libexif/exif-data.h>
int
main(int argc, char *argv[]) {
if(argc != 2) {
printf("Usage: foo <image>\n");
exit(1);
}
int orientation = 0;
ExifData *exifData = exif_data_new_from_file(argv[1]);
if (exifData) {
ExifByteOrder byteOrder = exif_data_get_byte_order(exifData);
ExifEntry *exifEntry = exif_data_get_entry(exifData,
EXIF_TAG_ORIENTATION);
if (exifEntry)
orientation = exif_get_short(exifEntry->data, byteOrder);
exif_data_free(exifData);
}
/*
0th Row 0th Column
1 top left side
2 top right side
3 bottom right side
4 bottom left side
5 left side top
6 right side top
7 right side bottom
8 left side bottom
*/
if(orientation != 0) {
printf("orientation == %d\n", orientation);
}
exit(0);
}
![[User Picture]](http://l-userpic.livejournal.com/5887295/515656) | From: jwz Sun, 28-Dec-2008 12:25 AM (UTC)
Re: Using libexif | (Link)
|
Well that's just silly. Finder and Preview are accomplishing it somehow, and they aren't using libexif to do it.
![[User Picture]](http://l-userpic.livejournal.com/142571/28061) | From: poon Sun, 28-Dec-2008 1:26 AM (UTC)
Re: Using libexif | (Link)
|
Alright, alright.
#import <Cocoa/Cocoa.h>
int main (int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *filename = [NSString stringWithCString:argv[1]];
NSData *imageData = [[NSData alloc] initWithContentsOfFile:filename];
NSImage *image = [[NSImage alloc] initWithData:imageData];
if(!image)
return 0;
CGImageSourceRef imageSource =
CGImageSourceCreateWithData ((CFDataRef)imageData, NULL);
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource,
0, NULL);
NSLog(@"orientation == %@",
CFDictionaryGetValue(properties, kCGImagePropertyOrientation));
[pool drain];
return 0;
}
![[User Picture]](http://l-userpic.livejournal.com/23403524/5465652) | From: tooluser Sun, 28-Dec-2008 5:16 PM (UTC)
Re: Using libexif | (Link)
|
What, were you just waiting for him to complain hard enough? We can probably take that for granted.
Thanks, I was curious about this, too.
![[User Picture]](http://l-userpic.livejournal.com/70952415/4224) | From: sol3 Sun, 28-Dec-2008 12:44 AM (UTC)
| (Link)
|
It looks like you want to be using ImageIO framework. Specifically a CGImageSource object, and one of the properties that you can pull out is kCGImagePropertyOrientation.
I've seen a bunch of apps get exif rotation wrong, including ones published by Flickr, so I guess it's sort of good to hear that it's not a total no-brainer to implement. | |