iOS_UIImage的方向(imageOrientation)

來源:互聯網
上載者:User

標籤: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)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.