標籤:tiff concat ret nim code 匹配 html 旋轉 ref
Demo
一.重現問題:
拍照獲得的圖片,由於尺寸不對,需要拆切.但是有的圖片拆切出來,方向就亂了.尋找了一些品質才知道.圖片還有個方向屬性! imageOrientation.
二.一個圖片包含兩個方面的資訊:
1.資料本身: 每個像素的顏色值.
2.檔案頭: 圖片的基本資料.比如:圖片的寬高.圖片的方向資訊.
三: 為什麼會有圖片方向?
為了讓照片可以真實的反應人們拍攝時看到的情境,現在很多相機中就加入了方向感應器,它能夠記錄下拍攝時相機的方向,並將這一資訊儲存在照片中。照片的儲存方式還是沒有任何改變,它仍然是以相機的座標系來儲存,只是當相機來瀏覽這些照片時,相機可以根據照片中的方向資訊,結合此時相機的方向,對照片進行旋轉,從而轉到適合人們觀看的角度。
四: 什麼叫EXIF?
維基百科上對其的解釋為:
可交換影像檔格式常被簡稱為Exif(Exchangeable image file format),是專門為數位相機的照片設定的,可以記錄數位照片的屬性資訊和拍攝資料… Exif可以附加於JPEG、TIFF、RIFF等檔案之中.
什麼叫Orientation?
在EXIF涵蓋的各種資訊之中,其中有一個叫做Orientation (rotation)的標籤,用於記錄映像的方向,這便是相機寫入方向資訊的最終位置。它總共定義了八個值:
注意:對於上面的八種方向中,加了*的並不常見,因為它們代表的是鏡像方向,如果不做任何的處理,不管相機以任何角度拍攝,都無法出現鏡像的情況。
這個表格代表什麼意義?我們來看第一行,值為1時,右邊兩列的值分別為:Row #0 is Top,Column #0 is Left side,其實很好理解,它表示照片的第一行位於頂端,而第一列位於左側,那麼這張照片自然就是以正常角度拍攝的。
五: 什麼時候會造成圖片方向不對?
用相機拍攝出來的照片含有EXIF資訊,UIImage的imageOrientation屬性指的就是EXIF中的orientation資訊。
如果我們忽略orientation資訊,而直接對照片進行像素處理或者drawInRect等操作,得到的結果是翻轉或者旋轉90之後的樣子。這是因為我們執行像素處理或者drawInRect等操作之後,imageOrientaion資訊被刪除了,imageOrientaion被重設為0,造成照片內容和imageOrientaion不匹配。
所以,在對照片進行處理之前,先將照片旋轉到正確的方向,並且返回的imageOrientaion為0。
六: 解決辦法:
下面這個方法就是一個UIImage category中的方法,用它可以達到以上目的。
方法一: 最直觀的方法.
- (UIImage *)fixOrientation { // No-op if the orientation is already correct if (self.imageOrientation == UIImageOrientationUp) return self; // We need to calculate the proper transformation to make the image upright. // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored. CGAffineTransform transform = CGAffineTransformIdentity; switch (self.imageOrientation) { case UIImageOrientationDown: case UIImageOrientationDownMirrored: transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height); transform = CGAffineTransformRotate(transform, M_PI); break; case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: transform = CGAffineTransformTranslate(transform, self.size.width, 0); transform = CGAffineTransformRotate(transform, M_PI_2); break; case UIImageOrientationRight: case UIImageOrientationRightMirrored: transform = CGAffineTransformTranslate(transform, 0, self.size.height); transform = CGAffineTransformRotate(transform, -M_PI_2); break; case UIImageOrientationUp: case UIImageOrientationUpMirrored: break; } switch (self.imageOrientation) { case UIImageOrientationUpMirrored: case UIImageOrientationDownMirrored: transform = CGAffineTransformTranslate(transform, self.size.width, 0); transform = CGAffineTransformScale(transform, -1, 1); break; case UIImageOrientationLeftMirrored: case UIImageOrientationRightMirrored: transform = CGAffineTransformTranslate(transform, self.size.height, 0); transform = CGAffineTransformScale(transform, -1, 1); break; case UIImageOrientationUp: case UIImageOrientationDown: case UIImageOrientationLeft: case UIImageOrientationRight: break; } // Now we draw the underlying CGImage into a new context, applying the transform // calculated above. CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height, CGImageGetBitsPerComponent(self.CGImage), 0, CGImageGetColorSpace(self.CGImage), CGImageGetBitmapInfo(self.CGImage)); CGContextConcatCTM(ctx, transform); switch (self.imageOrientation) { case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: case UIImageOrientationRight: case UIImageOrientationRightMirrored: // Grr... CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage); break; default: CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage); break; } // And now we just create a new UIImage from the drawing context CGImageRef cgimg = CGBitmapContextCreateImage(ctx); UIImage *img = [UIImage imageWithCGImage:cgimg]; CGContextRelease(ctx); CGImageRelease(cgimg); return img;}
方法二: 這裡是利用了UIImage中的drawInRect方法,它會將映像繪製到畫布上,並且已經考慮好了映像的方向.
- (UIImage *)normalizedImage { if (self.imageOrientation == UIImageOrientationUp) return self; UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale); [self drawInRect:(CGRect){0, 0, self.size}]; UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return normalizedImage;}
支援人員: http://www.cocoachina.com/ios/20150605/12021.html
iOS_UIImage的方向(imageOrientation)