Swift 3 和 CGContextDrawImage

Posted

技术标签:

【中文标题】Swift 3 和 CGContextDrawImage【英文标题】:Swift 3 and CGContextDrawImage 【发布时间】:2016-09-15 14:41:16 【问题描述】:

我想将此行翻译成 Swift 3 当前的语法代码,但似乎有一些问题:

CGContextDrawImage(context, CGRect(x:0.0,y: 0.0,width: image!.size.width,height: image!.size.height), image!.cgImage)

根据CoreGraphics.apinotesCGContextDrawImage被转换为CGContext.draw

Name: CGContextDrawImage
  # replaced by draw(_ image: CGImage, in rect: CGRect, byTiling: Bool = false)
  SwiftName: CGContext.__draw(self:in:image:)
  SwiftPrivate: true

当我尝试这样做时:

 CGContext.draw(context as! CGImage, in: CGRect(x:0.0, y:0.0, width: image!.size.width, height: image!.size.height), byTiling: false) 

似乎有一些简单的语法会干扰编译器但我看不到(实际上我收到了一个典型的模棱两可的错误):

谁能帮我解决这个新的 swift 3 语法代码?

【问题讨论】:

【参考方案1】:

你需要像CGContext的实例方法一样调用它:

context.draw(image!.cgImage!, in: CGRect(x: 0.0,y: 0.0,width: image!.size.width,height: image!.size.height))

检查the latest reference of CGContext

【讨论】:

谢谢,它运行良好。示例的“自我”初始属性分散了我的注意力:)【参考方案2】:

我为这个问题找到了另一个非常好的解决方案,我目前正在使用它。在使用 UIImagePickerController 捕获图像后,您只需要将图像作为参数传递给此方法。它适用于所有版本的 ios,也适用于相机的纵向和横向。它使用 UIImageOrientaiton 检查图像的 EXIF 属性并根据方向的值,它转换和缩放图像,因此您将获得与相机视图方向相同方向的相同返回图像。

在这里我保持了 3000 的最大分辨率,这样在您使用视网膜设备时图像质量不会受到特别破坏,但您可以根据需要更改其分辨率。

func scaleAndRotateImage(image: UIImage, MaxResolution iIntMaxResolution: Int) -> UIImage 
        let kMaxResolution = iIntMaxResolution
        let imgRef = image.cgImage!
        let width: CGFloat = CGFloat(imgRef.width)
        let height: CGFloat = CGFloat(imgRef.height)
        var transform = CGAffineTransform.identity
        var bounds = CGRect.init(x: 0, y: 0, width: width, height: height)

        if Int(width) > kMaxResolution || Int(height) > kMaxResolution 
            let ratio: CGFloat = width / height
            if ratio > 1 
                bounds.size.width = CGFloat(kMaxResolution)
                bounds.size.height = bounds.size.width / ratio
            
            else 
                bounds.size.height = CGFloat(kMaxResolution)
                bounds.size.width = bounds.size.height * ratio
            
        
        let scaleRatio: CGFloat = bounds.size.width / width
        let imageSize = CGSize.init(width: CGFloat(imgRef.width), height: CGFloat(imgRef.height))

        var boundHeight: CGFloat
        let orient = image.imageOrientation
        // The output below is limited by 1 KB.
        // Please Sign Up (Free!) to remove this limitation.

        switch orient 
        case .up:
            //EXIF = 1
            transform = CGAffineTransform.identity
        case .upMirrored:
            //EXIF = 2
            transform = CGAffineTransform.init(translationX: imageSize.width, y: 0.0)
            transform = transform.scaledBy(x: -1.0, y: 1.0)

        case .down:
            //EXIF = 3
            transform = CGAffineTransform.init(translationX: imageSize.width, y: imageSize.height)
            transform = transform.rotated(by: CGFloat(Double.pi / 2))

        case .downMirrored:
            //EXIF = 4
            transform = CGAffineTransform.init(translationX: 0.0, y: imageSize.height)
            transform = transform.scaledBy(x: 1.0, y: -1.0)
        case .leftMirrored:
            //EXIF = 5
            boundHeight = bounds.size.height
            bounds.size.height = bounds.size.width
            bounds.size.width = boundHeight
            transform = CGAffineTransform.init(translationX: imageSize.height, y: imageSize.width)

            transform = transform.scaledBy(x: -1.0, y: 1.0)
            transform = transform.rotated(by: CGFloat(Double.pi / 2) / 2.0)
            break

        default: print("Error in processing image")
        

        UIGraphicsBeginImageContext(bounds.size)
        let context = UIGraphicsGetCurrentContext()
        if orient == .right || orient == .left 
            context?.scaleBy(x: -scaleRatio, y: scaleRatio)
            context?.translateBy(x: -height, y: 0)
        
        else 
            context?.scaleBy(x: scaleRatio, y: -scaleRatio)
            context?.translateBy(x: 0, y: -height)
        
        context?.concatenate(transform)
        context?.draw(imgRef, in: CGRect.init(x: 0, y: 0, width: width, height: height))
        let imageCopy = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return imageCopy!
    

【讨论】:

以上是关于Swift 3 和 CGContextDrawImage的主要内容,如果未能解决你的问题,请参考以下文章

Mac - Swift 3 - 排队音频文件和播放

如何使用 Swift 2.3 和 3.0 编译模块?

Swift 3 和 CGContextDrawImage

Swift 3和UserDefaults

Alamofire 自定义响应从 Alamofire v1.3 迁移到 3.0(和 Swift 2 语法)

从 Firebase 检索和读取数据作为 NSArray (Swift 3)