[记一次坑]iOS相机拍摄的照片上传时会旋转90度及解决方法

2021-01-11  本文已影响0人  Aexsi

最近在接入一个拍照翻译的api时,发现用iPhone相机拍摄的照片传上去时返回的文字的rect死活不对,而去相册里把照片截屏再上传之又是正常的,在纠结排查了半个下午之后终于在输出照片的大小时发现了端倪。

CGFloat imageW = CGImageGetWidth(photo.CGImage);
CGFloat imageH = CGImageGetHeight(photo.CGImage);

在用上面的方法输出图片的高度和宽度时,发现用相机拍摄的照片输出的宽度居然大于高度,可UIimageView里显示的照片明显是高度比宽度大一些的,于是马上上网搜索有关资料,果不其然:

相机拍照后直接取出来的UIimage(用UIImagePickerControllerOriginalImage取出),它本身的imageOrientation属性是3,即UIImageOrientationRight。如果这个图片直接使用则没事,但是如果对它进行裁剪、缩放等操作后,它的这个imageOrientation属性会变成0。此时这张图片用在别的地方就会发生旋转。imageOrientation是只读的,不能直接修改其值。

最坑的地方在于,UIimageView在使用照片的时候会自动旋转回来,这给人的误导就是如果不通过CGImageGetHeight的方式输出照片的宽高,根本无法发现这个问题!因为你看到屏幕上显示的图片确实是正常的!

知道了原因,解决起来就简单了,给UIImage写一个分类可以轻松解决这个问题,只需调用以下方法即可:

+ (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;
}
上一篇下一篇

猜你喜欢

热点阅读