iOS中(相簿)攝像頭獲取的圖片上傳至伺服器被自動旋轉了
阿新 • • 發佈:2019-02-18
今天寫專案的時候發現, 通過相機(相簿)獲取到的圖片顯示是正的,但是上傳至伺服器後下次從伺服器讀取就被莫名其妙的旋轉了,開始時候以為是伺服器的原因,最後原來是我的原因:如果把通過相機獲取到的圖片,直接進行操作, 比如裁剪, 縮放, 則會把原圖片向右旋轉90度。
上網查後也有人說是這個原因:如果該圖片大於2M,會自動旋轉90度;否則不旋轉
- //get original photo from iOS photos
- //如果該圖片大於2M,會自動旋轉90度;否則不旋轉
-
UIImage* originalImg=[dict objectForKey:UIImagePickerControllerOriginalImage];
下邊說下解決方案:用相機拍攝出來的照片含有EXIF資訊,UIImage的imageOrientation屬性指的就是EXIF中的orientation資訊。
如果我們忽略orientation資訊,而直接對照片進行畫素處理或者drawInRect等操作,得到的結果是翻轉或者旋轉90之後的樣子。這是因為我們執行畫素處理或者drawInRect等操作之後,imageOrientaion資訊被刪除了,imageOrientaion被重設為0,造成照片內容和imageOrientaion不匹配。
所以,在對照片進行處理之前,先將照片旋轉到正確的方向,並且返回的imageOrientaion為0。
下面這個方法就是一個UIImage category中的方法,用它可以達到以上目的。
上程式碼:
- - (UIImage *)fixOrientation:(UIImage *)aImage {
- // No-op if the orientation is already correct
- if (aImage.imageOrientation == UIImageOrientationUp)
- return aImage;
- // 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 (aImage.imageOrientation) {
- case UIImageOrientationDown:
- case UIImageOrientationDownMirrored:
- transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
- transform = CGAffineTransformRotate(transform, M_PI);
- break;
- case UIImageOrientationLeft:
- case UIImageOrientationLeftMirrored:
- transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
- transform = CGAffineTransformRotate(transform, M_PI_2);
- break;
- case UIImageOrientationRight:
- case UIImageOrientationRightMirrored:
- transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
- transform = CGAffineTransformRotate(transform, -M_PI_2);
- break;
- default:
- break;
- }
- switch (aImage.imageOrientation) {
- case UIImageOrientationUpMirrored:
- case UIImageOrientationDownMirrored:
- transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
- transform = CGAffineTransformScale(transform, -1, 1);
- break;
- case UIImageOrientationLeftMirrored:
- case UIImageOrientationRightMirrored:
- transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
- transform = CGAffineTransformScale(transform, -1, 1);
- break;
- default:
- break;
- }
- // Now we draw the underlying CGImage into a new context, applying the transform
- // calculated above.
- CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
- CGImageGetBitsPerComponent(aImage.CGImage), 0,
- CGImageGetColorSpace(aImage.CGImage),
- CGImageGetBitmapInfo(aImage.CGImage));
- CGContextConcatCTM(ctx, transform);
- switch (aImage.imageOrientation) {
- case UIImageOrientationLeft:
- case UIImageOrientationLeftMirrored:
- case UIImageOrientationRight:
- case UIImageOrientationRightMirrored:
- // Grr...
- CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
- break;
- default:
- CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.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;
- }
上邊方法親自測試用過絕對靠譜。下面擷取專案中用此方法的片段:
- UIImageView *aImageView=[[[UIImageView alloc]init]autorelease];
- [aImageView setFrame:CGRectMake(INSETS-85, 5, PIC_WIDTH, PIC_HEIGHT)];
- aImageView = [addedPicArray objectAtIndex:0];
- NSData *imageData = UIImageJPEGRepresentation([self fixOrientation:aImageView.image], 0.1);
- // 上傳資訊至伺服器
- [self setPlayerImageRequest:imageData];//先上傳玩發表的圖片,然後在發表文字
經過轉後的image上傳至伺服器就是正常方向了。