【问题标题】:UIImage to CVPixelBuffer memory issueUIImage 到 CVPixelBuffer 内存问题
【发布时间】:2017-10-26 19:59:59
【问题描述】:

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

我已经想通了:

  1. 我使用仪器隔离了 image.draw 代码行中的内存问题。它显示了一段时间内保存在内存中的大量 CGImage 数据。
  2. 我隔离了函数,所以我确信问题不在于它之外(在调用者中)发生的事情,因为我从那里删除了所有代码并且内存不断增长。
  3. 我尝试将调用分派给此方法,但有一些延迟,以便让系统有时间解除分配,但它不起作用
  4. 我尝试在 autoreleasepool 中封装多个部分代码,但仍然无法正常工作。
  5. 我尝试了主线程、utility.qos 线程等,没有任何变化
  6. 我阅读了有关 StackOverflow 的所有其他问题,但似乎其他人的解决方案不适用于我的情况。

这是我的代码。感谢您提供任何帮助,因为我真的很想解决这个问题。

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
}

【问题讨论】:

  • 你能发布独立代码吗?例如exportingAdaptor 是什么?

标签: ios swift memory-management uiimage cvpixelbuffer


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 试过这样:var buffer = self.CreatePixelBufferFromImage(image); buffer = nil;它仍然无法正常工作。内存上升
    猜你喜欢
    • 2020-06-03
    • 2016-03-25
    • 2016-08-05
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-11
    • 2014-06-15
    相关资源
    最近更新 更多