iOS开发 相机拍摄的照片上传时会旋转90度的问题及解决方法

最近在接入一个拍照翻译的api时,发现用自带相机拍摄的照片传上去时返回的文字的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{
    // No-op if the orientation is already correct
    UIImage *image = self;
    if (image.imageOrientation == UIImageOrientationUp)
        return image;
    // 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 (image.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.width,0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, image.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        default:
            break;
    }
    switch (image.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, image.size.width,0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, image.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, image.size.width, image.size.height,
                                            CGImageGetBitsPerComponent(image.CGImage),0,
                                            CGImageGetColorSpace(image.CGImage),
                                            CGImageGetBitmapInfo(image.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (image.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx,CGRectMake(0,0,image.size.height,image.size.width), image.CGImage);
            break;
        default:
            CGContextDrawImage(ctx,CGRectMake(0,0,image.size.width,image.size.height), image.CGImage);
            break;
    }
    // And now we just create a new UIImage from the drawing context
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *resultImg = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    return resultImg;
}

使用时,直接调用- (UIImage *)fixOrientation方法即可

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容