вторник, 11 сентября 2012 г.

Create CGImageRef with EXIF Orientation

  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. static CGImageRef RotateWithEXIF (CGImageRef source, int orientation)  
  51. {  
  52.     switch (orientation)  
  53.     {  
  54.         case 2:  
  55.             return RotateImageWithFlip (source, 0, YES, NO);  
  56.             break;  
  57.         case 3:  
  58.             return RotateImageWithFlip (source, 0, YES, YES);  
  59.             break;  
  60.         case 4:  
  61.             return RotateImageWithFlip (source, 0, NO, YES);  
  62.             break;  
  63.   
  64.         case 5:  
  65.             return RotateImageWithFlip (source, 90, NO, YES);  
  66.             break;  
  67.         case 6:  
  68.             return RotateImageWithFlip (source, -90, NO, NO);  
  69.             break;  
  70.               
  71.         case 7:  
  72.             return RotateImageWithFlip (source, 90, YES, NO);  
  73.             break;  
  74.         case 8:  
  75.             return RotateImageWithFlip (source, -90, YES, YES);  
  76.             break;  
  77.               
  78.         default:  
  79.             break;  
  80.     }  
  81.       
  82.     return NULL;  
  83. }