如何在 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”是常量的组合,可确定像素格式的更多细节 CGImageAlphaInfoCGBitmapInfo。在这种情况下,我们说我们希望 alpha 通道是第一个(因此 ARGB 而不是 RGBA)并且我们希望使用颜色通道预乘 alpha 值的像素。

一旦你有了位图上下文,你就可以画你喜欢的东西了。你说你想在黑色背景上画一些线条 - 所以这只是给你黑色背景并留下线条作为 reader.

的练习

最后,您使用 makeImage 从上下文中得到 CGImage。如果你想要 UIImage,你可以用 UIImage(cgImage:)

构造一个

P.S。如果您想从原始内存块构建图像,或者通过从文件或其他来源流式传输数据,则可以使用 CGImageProvider。它基本上告诉系统如何获取图像数据。

在这种情况下,当我们创建位图上下文时,我们传入“nil”作为数据,要求OS为我们分配图像的帧缓冲区。