ios - CGContext.init() -- 不再允许 NULL 颜色空间

标签 ios swift core-graphics

TL;DR:在旧版 Obj-C 代码中,颜色空间参数值为 NULL。这在 Swift 等价物中是不允许的。使用什么值?

我继承了如下代码:

unsigned char pixel[1] = {0};
CGContextRef context = CGBitmapContextCreate(
    pixel,1, 1, 8, 1, NULL, (CGBitmapInfo)kCGImageAlphaOnly
);

Swift 4 CGContext 的端口很简单,除了 NULL 颜色空间值。使用合理的值,我从 CGContext.init?() 得到了 nil。我的翻译是:

var pixelValue = UInt8(0)
var pixel = Data(buffer: UnsafeBufferPointer(start:&pixelValue, count:1))
let context = CGContext(
    data            : &pixel,
    width           : 1,
    height          : 1,
    bitsPerComponent: 8,
    bytesPerRow     : 1,
    space           : CGColorSpace(name:CGColorSpace.genericRGBLinear)!,
    bitmapInfo      : CGImageAlphaInfo.alphaOnly.rawValue
)! // Returns nil; unwrapping crashes

:space 的合适值是多少? (我提供的值不返回 nil;它是 CGContext() 调用自身。

设置环境变量 CGBITMAP_CONTEXT_LOG_ERRORS 会产生如下错误日志:

Assertion failed: (0), function get_color_model_name, 
file /BuildRoot/Library/Caches/com.apple.xbs/Sources/Quartz2D_Sim/
Quartz2D-1129.2.1/CoreGraphics/API/CGBitmapContextInfo.c, line 210.

对于更多的背景故事,上下文用于通过以下方式查找 UIImage 中单个像素的 alpha 值:

unsigned char pixel[1] = {0};
CGContextRef context = CGBitmapContextCreate(pixel,1, 1, 8, 1, NULL, (CGBitmapInfo)kCGImageAlphaOnly);
UIGraphicsPushContext(context);
[image drawAtPoint:CGPointMake(-point.x, -point.y)];
UIGraphicsPopContext();
CGContextRelease(context);
CGFloat alpha = pixel[0]/255.0;

(我确实有寻找 alpha 的可能替代方案,但为了不影响遗留代码,我想保持这种方式。)

最佳答案

我最近处理过类似的主题,也许这个代码示例会对某人有所帮助:

let image = UIImage(named: "2.png")
guard let cgImage = image?.cgImage else {
    fatalError()
}

let width = cgImage.width
let height = cgImage.height
//CGColorSpaceCreateDeviceGray - 1 component, 8 bits
//i.e. 1px = 1byte
let bytesPerRow = width
let bitmapByteCount = width * height

let bitmapData: UnsafeMutablePointer<UInt8> = .allocate(capacity: bitmapByteCount)
defer {
    bitmapData.deallocate()
}
bitmapData.initialize(repeating: 0, count: bitmapByteCount)

guard let context = CGContext(data: bitmapData, width: width, height: height,
                              bitsPerComponent: 8, bytesPerRow: bytesPerRow,
                              space: CGColorSpaceCreateDeviceGray(), bitmapInfo: CGImageAlphaInfo.alphaOnly.rawValue) else {
                                fatalError()
}
//draw image to context
var rect = CGRect(x: 0, y: 0, width: width, height: height)
context.draw(cgImage, in: rect)

// Enumerate through all pixels
for row in 0..<height {
    for col in 0..<width {
        let alphaValue = bitmapData[row * width + col]
        if alphaValue != 0 {
            //visible pixel
        }
    }
}

关于ios - CGContext.init() -- 不再允许 NULL 颜色空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48195801/

相关文章:

ios - 没有设置触摸手势,但tabBar只响应长按。为什么?

ios - 在 iOS 中替换图像的特定颜色

iphone - CGPoint 等价于整数?

ios - 具有 2 个数据集的多折线图

ios - 使用 swift 3 解码字符串

ios - 调整字体大小以适合标签高度 - Swift 4、Xcode 9

ios - UIBezierPath 简单矩形

ios - 获取所有可供选择的文件和文件夹

python - 查找 APNS 证书文件是否有效的替代方法?

Swift 2.0 - `nil` 或 `0` 枚举参数