gpt4 book ai didi

ios - 对于 HEIC 图像来说,获取点上的像素颜色需要很长时间

转载 作者:行者123 更新时间:2023-11-29 05:41:34 25 4
gpt4 key购买 nike

下面的方法获取所选照片中特定点的像素颜色。当选择 JPG 时,下面的图像处理速度很快。当选择 HEIC 照片时,下面的图像处理速度很慢。速度可能慢约 40 倍(7 秒 vs 5 分钟)。

我想知道这是为什么以及我能做些什么来解决它?需要明确的是,下面的代码可以工作,只是需要很长时间来处理 HEIC。

class func getPixelColorAtPoint(point:CGPoint, sourceView: UIView) -> UIColor{

let pixel = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: 4)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
let context = CGContext(data: pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)
var color: UIColor? = nil

if let context = context {
context.translateBy(x: -point.x, y: -point.y)
sourceView.layer.render(in: context)

color = UIColor(red: CGFloat(pixel[0])/255.0,
green: CGFloat(pixel[1])/255.0,
blue: CGFloat(pixel[2])/255.0,
alpha: CGFloat(pixel[3])/255.0)

pixel.deallocate(capacity: 4)
}
return color!
}

最佳答案

如果需要 5 分钟,我假设您必须重复调用此例程,每次都渲染此 sourceView。您应该将整个 View 渲染到完整的像素缓冲区一次且仅一次,然后您可以有效地从此缓冲区中检索多个像素的颜色。

例如:

var data: Data?
var width: Int!
var height: Int!

func pixelColor(at point: CGPoint, for sourceView: UIView) -> UIColor? {
if data == nil { fillBuffer(for: sourceView) }

return data?.withUnsafeBytes { rawBufferPointer in
let pixels = rawBufferPointer.bindMemory(to: Pixel.self)
let pixel = pixels[Int(point.y) * width + Int(point.x)]
return pixel.color
}
}

func fillBuffer(for sourceView: UIView) {
// get image snapshot

let bounds = sourceView.bounds
let format = UIGraphicsImageRendererFormat()
format.scale = 1
let image = UIGraphicsImageRenderer(bounds: bounds, format: format).image { _ in
sourceView.drawHierarchy(in: bounds, afterScreenUpdates: false)
}
guard let cgImage = image.cgImage else { return }

// prepare to get pixel buffer

let colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
width = Int(bounds.width)
height = Int(bounds.height)

// populate and save pixel buffer

if let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: 8, bytesPerRow: 4 * width, space: colorSpace, bitmapInfo: bitmapInfo.rawValue) {
context.draw(cgImage, in: bounds)
data = context.data.flatMap { Data(bytes: $0, count: 4 * width * height) }
}
}

显然,可以按照您想要的方式将其渲染到缓冲区,但基本思想是将像素缓冲区保存到一些数据中,您可以从中快速检索颜色值。

顺便说一句,我认为使用struct(如下所示)来渲染稍微更直观的代码很有用,而不是单独导航 RGBA 字节:

struct Pixel {
let red: UInt8
let green: UInt8
let blue: UInt8
let alpha: UInt8
}

extension Pixel {
var color: UIColor {
return UIColor(red: CGFloat(red) / 255,
green: CGFloat(green) / 255,
blue: CGFloat(blue) / 255,
alpha: CGFloat(alpha) / 255)
}
}

恕我直言,更有趣的问题是为什么要检索多个像素的颜色。您是否真的需要单个像素的颜色,或者您是否根据结果(例如直方图、平均颜色等)进行一些计算? IE。如果您确实只需要逐像素的颜色,那很好,但如果您想要解决更广泛的问题,我们也许可以向您展示比逐像素处理更有效的方法。这些范围包括并行例程、vImage 高性能图像处理等。但是,如果不知道您在使用这些重复调用来检索像素颜色做什么,我们就不能说更多。

关于ios - 对于 HEIC 图像来说,获取点上的像素颜色需要很长时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56499993/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com