如何在 Swift 中创建空的彩色 CGImage canvas
How to create an empty, coloured CGImage canvas in Swift
我想在空白的 CGImage 黑色上画一些线 canvas。创建特定大小的空白 CGImage 应该是微不足道的事情,但我做不到。我试过扩展 CGImage init 吗?使用所需信息调用 self.init(width:height:...bitmapInfo:provider:...) 但我对 CGBitmapInfo 和 CGDataProvider 了解不够。
关于如何创建这个空 canvas 的任何帮助或指导?还有其他不使用 UIKit 的方法吗?
谢谢!
您不是在 CGImage
上画画,而是在 CGContext
上画画。您要做的是创建位图上下文,绘制到位图上下文中,然后从上下文位图缓冲区创建图像。这是我在 Playground 中输入的示例。
导入 UIKit
// CGContexts like rowbytes that are multiples of 16.
func goodBytesPerRow(_ width: Int) -> Int {
return (((width * 4) + 15) / 16) * 16
}
func drawMyImage() -> CGImage? {
let bounds = CGRect(x: 0, y:0, width: 200, height: 200)
let intWidth = Int(ceil(bounds.width))
let intHeight = Int(ceil(bounds.height))
let bitmapContext = CGContext(data: nil,
width: intWidth, height: intHeight,
bitsPerComponent: 8,
bytesPerRow: goodBytesPerRow(intWidth),
space: CGColorSpace(name: CGColorSpace.sRGB)!,
bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue)
if let cgContext = bitmapContext {
cgContext.saveGState()
cgContext.setFillColor(gray: 0, alpha: 1.0)
cgContext.fill(bounds)
/* ... do other drawing here ... */
cgContext.restoreGState()
return cgContext.makeImage()
}
return nil
}
let image = drawMyImage()
这是使用 32 位 ARGB 值绘制的。
Core Graphics 最喜欢它的行字节是 16 的倍数(或者至少在 2006 年我写一本 Quartz 2D 书时它是这样的)。因此,goodBytesPerRow
为 32 位 ARGB 像素计算给定宽度的 rowBytes,它是 16 的倍数。
“bitmapInfo”是常量的组合,可确定像素格式的更多细节 CGImageAlphaInfo
和 CGBitmapInfo
。在这种情况下,我们说我们希望 alpha 通道是第一个(因此 ARGB 而不是 RGBA)并且我们希望使用颜色通道预乘 alpha 值的像素。
一旦你有了位图上下文,你就可以画你喜欢的东西了。你说你想在黑色背景上画一些线条 - 所以这只是给你黑色背景并留下线条作为 reader.
的练习
最后,您使用 makeImage
从上下文中得到 CGImage
。如果你想要 UIImage
,你可以用 UIImage(cgImage:)
构造一个
P.S。如果您想从原始内存块构建图像,或者通过从文件或其他来源流式传输数据,则可以使用 CGImageProvider
。它基本上告诉系统如何获取图像数据。
在这种情况下,当我们创建位图上下文时,我们传入“nil”作为数据,要求OS为我们分配图像的帧缓冲区。
我想在空白的 CGImage 黑色上画一些线 canvas。创建特定大小的空白 CGImage 应该是微不足道的事情,但我做不到。我试过扩展 CGImage init 吗?使用所需信息调用 self.init(width:height:...bitmapInfo:provider:...) 但我对 CGBitmapInfo 和 CGDataProvider 了解不够。
关于如何创建这个空 canvas 的任何帮助或指导?还有其他不使用 UIKit 的方法吗?
谢谢!
您不是在 CGImage
上画画,而是在 CGContext
上画画。您要做的是创建位图上下文,绘制到位图上下文中,然后从上下文位图缓冲区创建图像。这是我在 Playground 中输入的示例。
导入 UIKit
// CGContexts like rowbytes that are multiples of 16.
func goodBytesPerRow(_ width: Int) -> Int {
return (((width * 4) + 15) / 16) * 16
}
func drawMyImage() -> CGImage? {
let bounds = CGRect(x: 0, y:0, width: 200, height: 200)
let intWidth = Int(ceil(bounds.width))
let intHeight = Int(ceil(bounds.height))
let bitmapContext = CGContext(data: nil,
width: intWidth, height: intHeight,
bitsPerComponent: 8,
bytesPerRow: goodBytesPerRow(intWidth),
space: CGColorSpace(name: CGColorSpace.sRGB)!,
bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue)
if let cgContext = bitmapContext {
cgContext.saveGState()
cgContext.setFillColor(gray: 0, alpha: 1.0)
cgContext.fill(bounds)
/* ... do other drawing here ... */
cgContext.restoreGState()
return cgContext.makeImage()
}
return nil
}
let image = drawMyImage()
这是使用 32 位 ARGB 值绘制的。
Core Graphics 最喜欢它的行字节是 16 的倍数(或者至少在 2006 年我写一本 Quartz 2D 书时它是这样的)。因此,goodBytesPerRow
为 32 位 ARGB 像素计算给定宽度的 rowBytes,它是 16 的倍数。
“bitmapInfo”是常量的组合,可确定像素格式的更多细节 CGImageAlphaInfo
和 CGBitmapInfo
。在这种情况下,我们说我们希望 alpha 通道是第一个(因此 ARGB 而不是 RGBA)并且我们希望使用颜色通道预乘 alpha 值的像素。
一旦你有了位图上下文,你就可以画你喜欢的东西了。你说你想在黑色背景上画一些线条 - 所以这只是给你黑色背景并留下线条作为 reader.
的练习最后,您使用 makeImage
从上下文中得到 CGImage
。如果你想要 UIImage
,你可以用 UIImage(cgImage:)
P.S。如果您想从原始内存块构建图像,或者通过从文件或其他来源流式传输数据,则可以使用 CGImageProvider
。它基本上告诉系统如何获取图像数据。
在这种情况下,当我们创建位图上下文时,我们传入“nil”作为数据,要求OS为我们分配图像的帧缓冲区。