如何在Swift中获取CGImage指定CGPoint位置对应的CGColor
Swift 实现从CGImage中获取指定CGPoint对应CGColor的方案
我们可以通过给CGImage添加扩展的方式实现需求,核心逻辑是将CGImage绘制到内存像素缓冲区中,计算目标点对应的像素偏移后读取RGBA值,最终生成CGColor。
完整实现代码
import CoreGraphics extension CGImage { /// 获取指定坐标点的像素颜色 /// - Parameter point: 目标点,坐标系为图像自身坐标系,原点在左上角 /// - Returns: 对应点的CGColor,坐标超出图像范围返回nil func getPixelColor(at point: CGPoint) -> CGColor? { // 坐标合法性校验 let imgWidth = self.width let imgHeight = self.height guard point.x >= 0, point.x < CGFloat(imgWidth), point.y >= 0, point.y < CGFloat(imgHeight) else { return nil } let bytesPerPixel = 4 let bytesPerRow = bytesPerPixel * imgWidth let bitsPerComponent = 8 let rgbColorSpace = CGColorSpaceCreateDeviceRGB() // 申请像素缓冲区内存 let pixelBuffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bytesPerRow * imgHeight) // 方法退出时自动释放缓冲区 defer { pixelBuffer.deallocate() } // 创建绘制上下文 guard let context = CGContext( data: pixelBuffer, width: imgWidth, height: imgHeight, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: rgbColorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue ) else { return nil } // 将CGImage绘制到上下文中,写入像素数据到缓冲区 context.draw(self, in: CGRect(x: 0, y: 0, width: imgWidth, height: imgHeight)) // 计算目标像素在缓冲区的偏移位置 let pixelIndex = Int(point.y) * imgWidth + Int(point.x) let red = CGFloat(pixelBuffer[pixelIndex * 4 + 0]) / 255.0 let green = CGFloat(pixelBuffer[pixelIndex * 4 + 1]) / 255.0 let blue = CGFloat(pixelBuffer[pixelIndex * 4 + 2]) / 255.0 let alpha = CGFloat(pixelBuffer[pixelIndex * 4 + 3]) / 255.0 return CGColor(red: red, green: green, blue: blue, alpha: alpha) } }
使用示例
// 替换为你的CGImage实例 let targetCGImage: CGImage = ... // 目标点:x=50,y=80 let targetPoint = CGPoint(x: 50, y: 80) if let color = targetCGImage.getPixelColor(at: targetPoint) { // 后续颜色处理逻辑 print("取色结果:\(color)") }
注意事项
- 方法入参的
point使用图像自身坐标系,原点在左上角,如果是从UIKit/AppKit的视图坐标转换而来,需要先完成坐标映射,避免取点位置错误。 - 上述代码适配通用的RGBA8格式CGImage,如果你的CGImage使用特殊颜色空间、非标准像素格式,需要对应调整
CGContext初始化的bitmapInfo和颜色空间参数。 - 如果需要频繁调用该方法获取多个点的颜色,建议复用生成的CGContext和像素缓冲区,避免重复创建带来的性能损耗。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

