среда, 20 июля 2011 г.

Как получить метаданные из NSImage

Получаем метаданные изображения.

+ (NSDictionary*) exif : (NSString*) file  
  1. {  
  2.     NSDictionary* dic = nil;        
  3.     NSURL* url = [ NSURL fileURLWithPath : file ];
  4.     if ( url )  
  5.     {  
  6.         CGImageSourceRef source = 
  7.         CGImageSourceCreateWithURL ( (CFURLRef) url, NULL);  
  8.           
  9.         if ( NULL == source )   
  10.         {  
  11. #ifdef _DEBUG  
  12.             CGImageSourceStatus status = CGImageSourceGetStatus ( source );  
  13.             NSLog ( @"Error: file name : %@ - Status: %d", file, status );  
  14. #endif            
  15.         }  
  16.         else  
  17.         {             
  18.             CFDictionaryRef metadataRef = 
  19.             CGImageSourceCopyPropertiesAtIndex ( source, 0, NULL );  
  20.             if ( metadataRef )   
  21.             {  
  22.                 NSDictionary* immutableMetadata = (NSDictionary *)metadataRef;  
  23.                 if ( immutableMetadata )  
  24.                 {                 
  25.                     dic =   
  26.                 [ NSDictionary dictionaryWithDictionary : (NSDictionary *)metadataRef ];  
  27.                 }                                          
  28.                   
  29.                 CFRelease ( metadataRef );  
  30.             }  
  31.               
  32.             CFRelease(source);  
  33.             source = nil;  
  34.         }  
  35.     }  
  36.       
  37.     return dic;  
  38. }  

Используем в коде - получение ориентации изображения из метаданных.

  1. NSDictionary* dic = [ ImageLoader exif : filename ];  
  2. NSLog(@"exif : %@", dic);  
  3. if ( dic )  
  4. {  
  5.     NSString* s     =   [ dic valueForKey : @"Orientation" ];  
  6.     NSLog(@"Image : %@ - orentation : %d", filename, [ s intValue ] );  
  7. }  


LOG

2011-07-21 00:20:40.990 test.app[12204:8003] exif : {
    ColorModel = RGB;
    DPIHeight = 72;
    DPIWidth = 72;
    Depth = 8;
    Orientation = 7;
    PixelHeight = 2592;
    PixelWidth = 3872;
    "{JFIF}" =     {
        DensityUnit = 1;
        JFIFVersion =         (
            1,
            1
        );
        XDensity = 72;
        YDensity = 72;
    };
    "{TIFF}" =     {
        Orientation = 7;
    };
}

2011-07-21 00:20:40.991 test.app[12204:8003] Image : /Users/alexey/Desktop/Works/EXIF Orientation Sample Images/7.jpg - orentation : 7

Как правильно преобразовать картинку с учетом ориентации
  1. static inline double rad (int alpha)  
  2. {  
  3.     return ((alpha * pi)/180);  
  4. }  
  5.   
  6. static CGImageRef RotateImageWithFlip (CGImageRef source, float angle, 
  7.                                    BOOL flipX, BOOL flipY)  
  8. {  
  9.     float fX    =  fabs ( cos ( rad ( angle ) ) );  
  10.     float fY    =  fabs ( sin ( rad ( angle ) ) );  
  11.       
  12.     float dW    =  (float)CGImageGetWidth  (source) * fX +
  13.                     (float)CGImageGetHeight (source) * fY;  
  14.     float dH    =  (float)CGImageGetWidth  (source) * fY +
  15.                     (float)CGImageGetHeight (source) * fX;  
  16.       
  17.     CGContextRef context = CGBitmapContextCreate (NULL,  
  18.                                           (size_t)dW, (size_t)dH,   
  19.                                           CGImageGetBitsPerComponent(source),   
  20.                                           0,   
  21.                                           CGImageGetColorSpace(source),  
  22.                                           kCGImageAlphaPremultipliedLast);  
  23.       
  24.     CGContextSetAllowsAntialiasing(context, NO);  
  25.     CGContextSetShouldAntialias(context, NO);  
  26.     CGContextSetInterpolationQuality (context, kCGInterpolationLow);  
  27.       
  28.     CGAffineTransform transform =
  29.     CGAffineTransformMakeTranslation(flipX?dW:0.0f,flipY?dH:0.0f);  
  30.     transform = CGAffineTransformScale (transform,flipX?-1.0:1.0f,flipY?-1.0: 1.0f);  
  31.   
  32.     if (0.0f != angle)  
  33.     {  
  34.         CGAffineTransform rot = CGAffineTransformMakeTranslation (dW*0.5f,dH*0.5f);  
  35.         rot                   = CGAffineTransformRotate(rot, rad ( angle ));  
  36.         rot                   = CGAffineTransformTranslate (rot,-dH*0.5f,-dW*0.5f);  
  37.         transform             = CGAffineTransformConcat(rot, transform);  
  38.     }  
  39.       
  40.     CGContextConcatCTM(context, transform);  
  41.       
  42.     CGContextDrawImage(context, CGRectMake (0, 0, CGImageGetWidth (source),   
  43.                                                     CGImageGetHeight (source)), source);      
  44.     CGContextFlush(context);      
  45.     CGImageRef rotated  =   CGBitmapContextCreateImage(context);  
  46.     CGContextRelease(context);  
  47.   
  48.     return rotated;  
  49. }  
  50.   
  51. static CGImageRef RotateWithEXIF (CGImageRef source, int orientation)  
  52. {  
  53.     switch (orientation)  
  54.     {  
  55.         case 2:  
  56.             return RotateImageWithFlip (source, 0, YES, NO);  
  57.             break;  
  58.         case 3:  
  59.             return RotateImageWithFlip (source, 0, YES, YES);  
  60.             break;  
  61.         case 4:  
  62.             return RotateImageWithFlip (source, 0, NO, YES);  
  63.             break;  
  64.   
  65.         case 5:  
  66.             return RotateImageWithFlip (source, 90, NO, YES);  
  67.             break;  
  68.         case 6:  
  69.             return RotateImageWithFlip (source, -90, NO, NO);  
  70.             break;  
  71.               
  72.         case 7:  
  73.             return RotateImageWithFlip (source, 90, YES, NO);  
  74.             break;  
  75.         case 8:  
  76.             return RotateImageWithFlip (source, -90, YES, YES);  
  77.             break;  
  78.               
  79.         default:  
  80.             break;  
  81.     }  
  82.       
  83.     return NULL;  
  84. }  

Комментариев нет: