代码之家  ›  专栏  ›  技术社区  ›  zeus

如何加载图像并根据其方向EXIF数据旋转,并将其保存到UIImageOrientationUp ExIF数据中

  •  1
  • zeus  · 技术社区  · 6 年前

    如何加载图像并根据其旋转 orientation exif 数据并保存 UIImageOrientationUp EXIF数据(或没有任何方向的EXIF数据),以便不处理EXIF定位数据的软件将正确显示图像?

    2 回复  |  直到 6 年前
        1
  •  2
  •   AamirR    6 年前

    加载图像非常简单:

    UIImage *image = [UIImage imageNamed:@"NameOfImageHere"];
    

    或者如果你有图像数据:

    NSData *imageData = [[NSData alloc] init];
    UIImage *image = [UIImage imageWithData: imageData];
    

    下面的方法将帮助您使用EXIF数据修复定位 UIImage

    - (UIImage *)imageByFixingOrientation {
    
        UIImage *image = self;
    
        if (image.imageOrientation == UIImageOrientationUp) return image;
    
        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;
            case UIImageOrientationUp:
            case UIImageOrientationUpMirrored:
                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;
            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, 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:
                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 *img = [UIImage imageWithCGImage:cgimg];
        CGContextRelease(ctx);
        CGImageRelease(cgimg);
        return img;
    }
    
        2
  •  2
  •   AamirR    6 年前

    SWIFT 4相当于我以前的objective-c方法的扩展:

    extension UIImage {
    
        func byFixingOrientation(andResizingImageToNewSize newSize: CGSize? = nil) -> UIImage {
    
            guard let cgImage = self.cgImage else { return self }
    
            let orientation = self.imageOrientation
            guard orientation != .up else { return UIImage(cgImage: cgImage, scale: 1, orientation: .up) }
    
            var transform = CGAffineTransform.identity
            let size = newSize ?? self.size
    
            if (orientation == .down || orientation == .downMirrored) {
                transform = transform.translatedBy(x: size.width, y: size.height)
                transform = transform.rotated(by: .pi)
            }
            else if (orientation == .left || orientation == .leftMirrored) {
                transform = transform.translatedBy(x: size.width, y: 0)
                transform = transform.rotated(by: CGFloat.pi / 2)
            }
            else if (orientation == .right || orientation == .rightMirrored) {
                transform = transform.translatedBy(x: 0, y: size.height)
                transform = transform.rotated(by: -(CGFloat.pi / 2))
            }
    
            if (orientation == .upMirrored || orientation == .downMirrored) {
                transform = transform.translatedBy(x: size.width, y: 0);
                transform = transform.scaledBy(x: -1, y: 1)
            }
            else if (orientation == .leftMirrored || orientation == .rightMirrored) {
                transform = transform.translatedBy(x: size.height, y: 0)
                transform = transform.scaledBy(x: -1, y: 1)
            }
    
            // Now we draw the underlying CGImage into a new context, applying the transform calculated above.
            guard let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height),
                                      bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0,
                                      space: cgImage.colorSpace!, bitmapInfo: cgImage.bitmapInfo.rawValue)
            else {
                return UIImage(cgImage: cgImage, scale: 1, orientation: orientation)
            }
    
            ctx.concatenate(transform)
    
            // Create a new UIImage from the drawing context
            switch (orientation) {
            case .left, .leftMirrored, .right, .rightMirrored:
                ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.height, height: size.width))
            default:
                ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
            }
    
            return UIImage(cgImage: ctx.makeImage() ?? cgImage, scale: 1, orientation: .up)
        }
    }
    

    用法-1

    let newImage = image.byFixingOrientation()
    

    用法-2(固定方向并将图像调整为新大小)

    let newImage = image.byFixingOrientation(andResizingImageToNewSize: CGSize(width: 200, height: 200))
    
    推荐文章