我有一些在CGImage中采样像素的代码。我采样的图像是完全红色的。当我采样全尺寸图像时,结果颜色都是红色的阴影,但是如果我采样从同一URL创建的缩略图,结果颜色都是黄色的阴影。我从图像本身提取所有常量,所以在这里真的很困惑。
func analayze(imageAtURL url: URL) async throws -> [Color: Int] {
guard let imgSource = CGImageSourceCreateWithURL(url as CFURL, nil) else {
throw Error.cantLoadImage(url)
}
let cgImage: CGImage
switch optimization {
case .fullSize:
guard let img = CGImageSourceCreateImageAtIndex(imgSource, 0, nil) else {
throw Error.cantInstantiateImage(url)
}
cgImage = img
case let .scale(maxSide):
let options: [CFString: Any] = [
kCGImageSourceCreateThumbnailFromImageAlways: true as CFBoolean,
kCGImageSourceThumbnailMaxPixelSize: maxSide as CFNumber
]
guard let img = CGImageSourceCreateThumbnailAtIndex(imgSource, 0, options as CFDictionary) else {
throw Error.cantInstantiateImage(url)
}
cgImage = img
default:
throw Error.unsupportedOptimization(optimization)
}
let width = cgImage.width
let height = cgImage.height
let bytesPerRow = cgImage.bytesPerRow
let bytesPerPixel = bytesPerRow / width
let bitsPerComponent = cgImage.bitsPerComponent
assert(bitsPerComponent == 8, "Expected 8 bits per component, got \(bitsPerComponent)")
guard let pixelData = cgImage.dataProvider?.data else {
throw Error.contextHasNoData
}
guard let unsafePointer = CFDataGetBytePtr(pixelData) else {
throw Error.cantCreatePointer
}
let unsafeRawPointer = UnsafeRawPointer(unsafePointer)
let points = pointsInRect(width: width, height: height)
@Sendable
func findClosestColorInTable(for point: DiscretePoint) -> Color? {
let offset = (point.y * bytesPerRow) + (point.x * bytesPerPixel)
let red = CGFloat(unsafeRawPointer.load(fromByteOffset: offset, as: UInt8.self)) / 255
let green = CGFloat(unsafeRawPointer.load(fromByteOffset: offset + 1, as: UInt8.self)) / 255
let blue = CGFloat(unsafeRawPointer.load(fromByteOffset: offset + 2, as: UInt8.self)) / 255
let imgColor = Color(r: red, g: green, b: blue)
// let nearestNeighbor = self.colorTree.nearest(to: imgColor)
// return nearestNeighbor
return imgColor
}
字符串
以下是全尺寸方法的图像和结果:
的数据
对于缩放方法:
的
1条答案
按热度按时间bvk5enib1#
正如@HangarRash所指出的,CGImageSourceData ThumbnailAtIndex并不保证它会返回具有线性RGB颜色空间的RGB(A)数据,这似乎是你在这里假设的。虽然你可以深入研究数据格式的所有细节,但如果性能不是绝对重要的,我建议你重新-将缩略图绘制到一个CGContext中,它具有你想要的像素布局和颜色空间。这将简单得多,让CoreGraphics为你做这项工作。
如果你需要避免额外的往返,请参阅HangarRash关于在哪里查找信息的评论,尽管你可能还需要检查颜色空间以确保你使用了正确的转换。这很复杂,所以我只在你绝对需要的时候推荐它。在上下文中绘制会更容易保持一致。