生成的 CGImage 总是模糊
Generated CGImage always blurry
所以我一直在开发一个 "drawing" 小应用程序,用户可以在其中将图像绘制到网格上 canvas(基本上是创建像素艺术)。我想创建一个导出此 canvas 的函数(将其视为 UIColor
的数组,然后我将其转换为 RawPixel
,这是我需要的一个简单的颜色容器,因为实际 RGB 值需要 UInt8
以便我可以将其保存到 CGImage)。
到目前为止一切顺利。我想做的是让用户可以选择将他们当前的绘图作为图像保存到照片中。这就是问题开始的地方。这是在屏幕上绘制的图像:
但是当我导出这个时,图像看起来是这样的……超级模糊而且非常小。现在,我可以处理微小的问题,但我不知道如何解决模糊问题。
其实我把生成的CGImage
放到一个UIImageView
里,然后设置imgViewQR.layer.magnificationFilter = kCAFilterNearest
,然后看起来crystal就清楚了。但是当我 将绘图保存 到照片应用程序时,我希望这种特殊行为能够持续存在。我真的不知道在哪里搜索,所以任何帮助将不胜感激!!!
这是我使用相关颜色加载 "canvas" 以及将其保存到照片的方法。
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)
好吧,所以我最终找到的解决方案如下(这有点骇人听闻,但它确实有效,现在关于像素边缘的一切都crystal清楚了,而且你可以实际导出它到你想要的任何大小的实际图像!):
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
,生成清晰的图像,然后简单地截图并保存到照片。
所以我一直在开发一个 "drawing" 小应用程序,用户可以在其中将图像绘制到网格上 canvas(基本上是创建像素艺术)。我想创建一个导出此 canvas 的函数(将其视为 UIColor
的数组,然后我将其转换为 RawPixel
,这是我需要的一个简单的颜色容器,因为实际 RGB 值需要 UInt8
以便我可以将其保存到 CGImage)。
到目前为止一切顺利。我想做的是让用户可以选择将他们当前的绘图作为图像保存到照片中。这就是问题开始的地方。这是在屏幕上绘制的图像:
但是当我导出这个时,图像看起来是这样的……超级模糊而且非常小。现在,我可以处理微小的问题,但我不知道如何解决模糊问题。
其实我把生成的CGImage
放到一个UIImageView
里,然后设置imgViewQR.layer.magnificationFilter = kCAFilterNearest
,然后看起来crystal就清楚了。但是当我 将绘图保存 到照片应用程序时,我希望这种特殊行为能够持续存在。我真的不知道在哪里搜索,所以任何帮助将不胜感激!!!
这是我使用相关颜色加载 "canvas" 以及将其保存到照片的方法。
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)
好吧,所以我最终找到的解决方案如下(这有点骇人听闻,但它确实有效,现在关于像素边缘的一切都crystal清楚了,而且你可以实际导出它到你想要的任何大小的实际图像!):
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
,生成清晰的图像,然后简单地截图并保存到照片。