среда, 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. }  

понедельник, 4 июля 2011 г.

Griffin PowerMate ( манипулятор для компьютера )

Обладаю огромной страстью, к разным прикольным девайсам для компа. На просторах инета был обнаружен, весьма занимательный экземпляр. Чудо колесо, стальное колесо, шайба, как ни называй это устройство Griffin PowerMate. Определенно разнообразит ваш компьютерный быт. Т.к. покупал для своего эппл ноутбука. Не могу сказать, как оно работает под виндой. Под маком все работает, как положено.

Плюсы
- необычность
- неоновая подсветка, можно регулировать, моргание, плавное угасание...
- стальной корпус, подкупает своей "металичностью"
- есть специальное ПО, для удобной настройки

Минусы
- провода usb ( по аналогии с apple track pad, сделать блютуз версию устройства )
- подсветку надо ручками отключать, напрягает что подсветка будет всегда включена при каждой перезагрузке системы
- для разработки под эту штуковину нужен SDK от производителя ( support упорно молчит на предмет, как получить инструментарий разработчика )