gpt4 book ai didi

ios - OpenCV MatToUIImage 导致内存泄漏

转载 作者:太空宇宙 更新时间:2023-11-03 21:11:01 43 4
gpt4 key购买 nike

我的项目正在使用适用于 iOS (2.4.9) 的 openCV。并且我发现函数MatToUIImage会导致内存泄漏,而且它只发生在iOS 10.X上。

在我将此功能 (2.4.9) 更新到最新 (3.2.0) 版本后,一切正常。唯一的区别是 CGBitmapInfo

谁能告诉我为什么?

2.4.9

UIImage* MatToUIImage(const cv::Mat& image) {

NSData *data = [NSData dataWithBytes:image.data
length:image.elemSize()*image.total()];

CGColorSpaceRef colorSpace;

if (image.elemSize() == 1) {
colorSpace = CGColorSpaceCreateDeviceGray();
} else {
colorSpace = CGColorSpaceCreateDeviceRGB();
}

CGDataProviderRef provider =
CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

// Creating CGImage from cv::Mat
CGImageRef imageRef = CGImageCreate(image.cols,
image.rows,
8,
8 * image.elemSize(),
image.step.p[0],
colorSpace,
kCGImageAlphaNone|
kCGBitmapByteOrderDefault,
provider,
NULL,
false,
kCGRenderingIntentDefault
);


// Getting UIImage from CGImage
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);

return finalImage;
}

3.2.0

UIImage* MatToUIImage(const cv::Mat& image) {

NSData *data = [NSData dataWithBytes:image.data
length:image.elemSize()*image.total()];

CGColorSpaceRef colorSpace;

if (image.elemSize() == 1) {
colorSpace = CGColorSpaceCreateDeviceGray();
} else {
colorSpace = CGColorSpaceCreateDeviceRGB();
}

CGDataProviderRef provider =
CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

// Preserve alpha transparency, if exists
bool alpha = image.channels() == 4;
CGBitmapInfo bitmapInfo = (alpha ? kCGImageAlphaLast : kCGImageAlphaNone) | kCGBitmapByteOrderDefault;

// Creating CGImage from cv::Mat
CGImageRef imageRef = CGImageCreate(image.cols,
image.rows,
8,
8 * image.elemSize(),
image.step.p[0],
colorSpace,
bitmapInfo,
provider,
NULL,
false,
kCGRenderingIntentDefault
);


// Getting UIImage from CGImage
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);

return finalImage;
}

最佳答案

重要更新(5.06.2017) 最后,手动执行 CFRelease 被证明是个坏主意,因为它带来的麻烦多于解决的问题!不过,它给了我一个线索,即泄漏与 NSData(不)释放有某种联系。

我注意到,当从后台线程中的 block 调用时,它会按预期使用 ARC 自动释放,如下所示:

- (void)runInBackgroundWithImageBuffer:(CVImageBufferRef)imageBuffer
callback:(void (^)())callback {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
[self processImageBuffer:imageBuffer];
if (callback != nil) {
callback();
}
});
}

- (void)previewOpenCVImage:(cv::Mat *)image {
UIImage *preview = MatToUIImage(*image);

dispatch_async(dispatch_get_main_queue(), ^{
// _imagePreview has (UIImageView *) type
[_imagePreview setImage:preview];
});
}

我可以确认 iPhone 模拟器。似乎当前的 MatToUIImage 实现会导致模拟器出现内存泄漏。而且我无法在设备上重现它。

出于某种原因,分析器未检测到它们,但多次调用后内存使用量激增。

我添加了一些调整以使其工作:

  1. 在返回最终图像之前添加行 CFRelease((CFTypeRef)data)

  2. 当不需要图像时,我们需要执行 CFRelease(image.CGImage) 并且可能需要执行 CFRelease((CFTypeRef)image)

希望对您有所帮助。其实我不完全明白为什么会这样,谁在持有引用,为什么我们需要手动执行发布。

关于ios - OpenCV MatToUIImage 导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43975953/

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