UIImage方向问题在Swift中的处理方法

5
我用Swift编写了以下代码,使用AVFoundation库来捕获图像:
@IBAction func cameraButtonWasPressed(sender: AnyObject) {

    if let videoConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo){
        stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection){
            (imageSampleBuffer : CMSampleBuffer!, _) in

            let imageDataJpeg = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)

            var pickedImage: UIImage = UIImage(data: imageDataJpeg)!

            let library = ALAssetsLibrary()
            library.writeImageToSavedPhotosAlbum(pickedImage.CGImage,
                metadata:nil,
                completionBlock:nil)

        }


    }

}

它可以正常工作,但是当我进入相册时,图像显示逆时针旋转了90度。

有人能给我一个提示在哪里找到解决方法吗?


为什么使用AVFoundation捕获图像时,预设分辨率为1280x720的情况下,实际得到的是480x640的图像?提示:https://dev59.com/AlrUa4cB1Zd3GeqPfwbd - Robert Gummesson
设置视频连接方向和创建新的UIImage似乎不起作用。不确定我是否做错了什么。 - Rui Gomes
3个回答

7
也许这段Swift代码可以帮助你。
//correctlyOrientedImage.swift

import UIKit

extension UIImage {

    public func correctlyOrientedImage() -> UIImage {
        if self.imageOrientation == UIImageOrientation.Up {
            return self
        }

        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        self.drawInRect(CGRectMake(0, 0, self.size.width, self.size.height))
        var normalizedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        return normalizedImage;
    }
}

我在stackoverflow的某个地方看到了这个,然后也将其整合到我的项目中。


2

您应该使用略有不同的writeImage方法:

(1) 从UIImage的imageOrientation属性(一个枚举)获取方向,并将其转换为ALAssetOrientation(一个与UIImageOrientation具有相同Int值的枚举)

 var orientation : ALAssetOrientation = ALAssetOrientation(rawValue:           
                                        pickedImage.imageOrientation.rawValue)!

(2)在ALAssetLibrary上使用类似但不同的方法

library.writeImageToSavedPhotosAlbum(
                pickedImage.CGImage,
                orientation: orientation,
                completionBlock:nil)

这对我来说在Objective-C中可行... 我试着将其翻译成Swift(如上所述),但我收到了编译器警告。

无法使用类型为“(CGImage!,orientation:ALAssetOrientation,completionBlock:NilLiteralConvertible)”的参数列表调用“writeImageToSavedPhotosAlbum”

也许你可以尝试一下(我没有时间构建完整的AVFoundation管道来确定这一点)
如果你不能让它工作,另一个解决方案是从sampleBuffer中提取exif元数据并将其传递给你已经使用的方法。 library.writeImageToSavedPhotosAlbum(pickedImage.CGImage, metadata:nil, completionBlock:nil

感谢@foundry的好答案!你解决了我的问题https://dev59.com/iYjca4cB1Zd3GeqPwGfJ#28845429。如果你想回答,我会将其标记为正确答案。 - benLIVE
@benLIVE - 你使用哪个版本?是使用 orientation 版本还是提取元数据并使用 metadata 版本? - foundry
使用方向。我之前使用的是带有元数据的writeImageToSavedPhotosAlbum方法,并且像您的示例一样更改了方向。知道一种编辑元数据的方法会很好,因为不仅有方向,还有地理位置等其他信息。@foundry - benLIVE

0

Swift 5

extension UIImage {
    public func correctlyOrientedImage() -> UIImage {
        if self.imageOrientation == UIImage.Orientation.up {
            return self
        }
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        self.draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
        let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()!;
        UIGraphicsEndImageContext();

        return normalizedImage;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接