Swift - 选取 UIImage 的像素颜色 - 内存崩溃

Swift - Picking pixel colour of UIImage - memory crash

我想在 Swift 3 中选择 UIImage 的特定像素的颜色,这个方法被调用了 ~10k 次。

 func pixelColour(_ pixelPosition: CGPoint) {

    if !CGRect(x: 0.0, y: 0.0, width: self.size.width, height: self.size.height).contains(pixelPosition) {
        return false
    }


    let pointX = trunc(pixelPosition.x);
    let pointY = trunc(pixelPosition.y);

    let cgImage = self.cgImage;
    let width = self.size.width;
    let height = self.size.height;

    let colorSpace = CGColorSpaceCreateDeviceRGB();
    let bytesPerPixel = 4;
    let bytesPerRow = bytesPerPixel * 1;
    let bitsPerComponent = 8;
    let pixelData =  UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: 4)
    let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)

    let context = CGContext(data: pixelData, width: 1, height: 1, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)

    context?.setBlendMode(CGBlendMode.copy);
    context?.translateBy(x: -pointX, y: pointY-CGFloat(height));

    // This line takes too much memory, how to release memory here?
    context?.draw(cgImage!, in: CGRect(x: 0.0, y: 0.0, width: CGFloat(width), height: CGFloat(height)));




 print("\(pixelData[0]) \(pixelData[1])  \(pixelData[2]) ")
    pixelData.deallocate(capacity: 4)


}

不幸的是,似乎没有释放内存,因为它在检查 ~500 像素后崩溃。我该如何解决这个问题?

您没有说明 pixelColour 是如何调用的,但我认为它处于某种循环中。如果是这样,请用 autoreleasepool{...} 调用包围对 pixelColour 的重复调用,以释放每次循环中累积的内存:

let p = // next CGPoint
autoreleasepool {
    pixelColour(p)
}

取自How do I get the color of a pixel in a UIImage with Swift?

并转换为Swift 3

extension UIImage{
    func getPixelColor(pos: CGPoint) -> UIColor? {
        guard let provider=cgImage?.dataProvider else{
            return nil
        }
        let pixelData = provider.data
        let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)

        let pixelInfo: Int = ((Int(self.size.width) * Int(pos.y)) + Int(pos.x)) * 4

        let r = CGFloat(data[pixelInfo]) / CGFloat(255.0)
        let g = CGFloat(data[pixelInfo+1]) / CGFloat(255.0)
        let b = CGFloat(data[pixelInfo+2]) / CGFloat(255.0)
        let a = CGFloat(data[pixelInfo+3]) / CGFloat(255.0)

        return UIColor(red: r, green: g, blue: b, alpha: a)
    }
}

这不会占用太多内存,因为它使用指针,因此不会加载整个图像。

希望对您有所帮助