UIImage to CVPixelBuffer memory issue

时间:2017-05-26 02:55:58

标签: ios swift memory-management uiimage cvpixelbuffer

我有一个swift函数,它接受一个UIImage并返回一个CVPixelBuffer。多次运行此功能时,内存不断增长,导致崩溃。

我已经想到了:

  1. 使用乐器我在image.draw代码行中隔离了内存问题。它显示了很多CGImage数据随时间保留在内存中。
  2. 我隔离了这个函数,所以我确定问题不在于它之外的事情(在调用者中),因为我从那里删除了所有代码并且内存不断增长。
  3. 我尝试调度此方法,但有一些延迟,以便给系统释放时间,但是它不起作用
  4. 我尝试在autoreleasepool中包装多个部分代码,但仍无法正常工作。
  5. 我尝试了主线程,在utility.qos线程等,没有任何改变
  6. 我在StackOverflow上阅读了其他所有问题,但看起来其他人的解决方案在我的情况下不起作用。
  7. 这是我的代码。任何帮助都表示赞赏,因为我真的很喜欢这个。

    fileprivate func CreatePixelBufferFromImage(_ image: UIImage) -> CVPixelBuffer?{
    
        let size = image.size;
    
        var pxbuffer : CVPixelBuffer?
    
        let status = CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, self.exportingAdaptor!.pixelBufferPool!, &pxbuffer)
    
        guard (status == kCVReturnSuccess) else{
            return nil
        }
    
        CVPixelBufferLockBaseAddress(pxbuffer!, CVPixelBufferLockFlags(rawValue: 0));
        let pxdata = CVPixelBufferGetBaseAddress(pxbuffer!);
    
        let rgbColorSpace = CGColorSpaceCreateDeviceRGB();
        let context = CGContext(data: pxdata, width: Int(size.width),
                                height: Int(size.height), bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pxbuffer!), space: rgbColorSpace,
                                bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue);
    
        context?.translateBy(x: 0, y: image.size.height);
        context?.scaleBy(x: 1.0, y: -1.0);
    
        UIGraphicsPushContext(context!)
        image.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height));
        //
        UIGraphicsPopContext()
        CVPixelBufferUnlockBaseAddress(pxbuffer!, CVPixelBufferLockFlags(rawValue: 0));
    
        return pxbuffer
    }
    

2 个答案:

答案 0 :(得分:2)

我发现问题不是像素缓冲,而是图像参考 当我在上下文中绘制图像时,看起来(这只是我对此行为的看法),很多图像像素数据都存储在image.cgimage对象中。所以我通过释放我对每次调用此函数后绘制的图像的引用来解决,并且内存在所有进程中保持稳定。

答案 1 :(得分:0)

您需要删除您创建的引用,或者像素缓冲区将保持不变,然后在每次调用时创建一个新的引用。将ref放到像素缓冲区会将其放回池中,以便在下次调用时使用它。