生成的 CGImage 总是模糊的

Posted

技术标签:

【中文标题】生成的 CGImage 总是模糊的【英文标题】:Generated CGImage always blurry 【发布时间】:2018-08-08 13:38:58 【问题描述】:

所以我一直在开发一个小的“绘图”应用程序,用户可以在其中将图像绘制到网格画布上(基本上是创建像素艺术)。我想创建一个导出此画布的函数(将其视为UIColors 的数组,然后将其转换为RawPixel,这是我需要的一个简单颜色容器,因为实际的RGB 值需要为@987654327 @ 所以我可以把它保存到一个 CGImage 中)。

到目前为止一切顺利。我想做的是让用户可以选择将他们当前的绘图作为图像保存到照片中。这就是问题开始的地方。这是在屏幕上绘制的图像:

但是当我导出它时,这就是图像的样子……超级模糊而且非常小。现在,我可以使用微小的东西,但我不知道如何解决模糊。

我其实已经把生成的CGImage放到了UIImageView里,设置了imgViewQR.layer.magnificationFilter = kCAFilterNearest,然后就看的一清二楚了。但是,当我将绘图保存到照片应用程序时,我希望这种特殊行为能够持续存在。我真的不知道在哪里搜索,所以任何帮助将不胜感激!!!

这是我用来加载带有相关颜色的“画布”以及如何将其保存到照片的方法。

    var rawPixelArray = [RawPixel]()

    guard let canvasColorArray = self.canvasView?.canvas.getPixelColorArray(),
        let canvasWidth = self.canvasView?.canvas.getAmountOfPixelsForWidth(),
        let canvasHeight = self.canvasView?.canvas.getAmountofPixelsForHeight() else 
            return
    

    canvasColorArray.forEach  (color) in
        let rawPixel = RawPixel(inputColor: color)
        rawPixelArray.append(rawPixel)
    

    let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
    var data = rawPixelArray
    let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
    guard let dataProvider = CGDataProvider(data: NSData(bytes: &data,
                                                         length: data.count * MemoryLayout<RawPixel>.size)
        ) else  return 

    guard let exportedCGImage = CGImage.init(width: canvasWidth, height: canvasHeight, bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: canvasWidth * (MemoryLayout<RawPixel>.size), space: rgbColorSpace, bitmapInfo: bitmapInfo, provider: dataProvider, decode: nil, shouldInterpolate: false, intent: .defaultIntent) else 
        print("CGImage could not be created.")
        return
    

    let exportedUIImage = UIImage(cgImage: exportedCGImage)
    let imageView = UIImageView(image: exportedUIImage)

    UIImageWriteToSavedPhotosAlbum(imageView.image!, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)

【问题讨论】:

我认为您需要在保存时将图像扩展为 2x 或 3x。 我想我发现了与您的建议类似的东西!谢谢,我会在一分钟内回答这个问题。 【参考方案1】:

好的,所以我最终找到的解决方案如下(这有点像 hack,但它可以工作,而且现在像素边缘的一切都非常清晰,而且您实际上可以将其导出为任何大小的实际你想要的图片!):

    let exportedUIImage = UIImage(cgImage: exportedCGImage)
    let imageView = UIImageView(image: exportedUIImage)
    imageView.layer.magnificationFilter = kCAFilterNearest
    imageView.frame = CGRect(x: 5, y: 5, width: yourDesiredWidth, height: yourDesiredHeight) 
//just remember to yourDesiredWidth and yourDesiredHeight according to your actual drawing width/drawing height. 

    UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, imageView.isOpaque, 0.0)
    imageView.drawHierarchy(in: imageView.bounds, afterScreenUpdates: true)
    let snapshotImageFromMyView = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

所以我所做的是,我基本上是创建一个(不可见的)UIImageView,将magnificationFilter 转换为kCAFilterNearest,它会生成一个清晰、清晰的图像,然后简单地将其截屏并保存到照片中。

【讨论】:

以上是关于生成的 CGImage 总是模糊的的主要内容,如果未能解决你的问题,请参考以下文章

使用 CGImage / CGLayer 在另一个线程中绘图

通过 Core Image 框架复制结果 `func masking(_ mask: CGImage) -> CGImage?`

从文件创建的CGImage可以为空吗

为啥我的 CGImage 是 UIImage 大小的 3 倍

Swift NSImage到CGImage

如何在 Swift 中将 CGImage 保存到数据中?