在这里发布这个问题之前,我已经阅读了所有材料和相似的帖子,但我无法得到主要的"想法"正在发生的事情以及如何解决这个问题,在类似的问题中,每个人都在用@autoreleasepool
解决这个问题,在这种情况下,我无法实现我的目标。因此,在将cvMat转换为UIImage时,我会根据大小增加内存。
以下是我在将mat转换为uiimage之前所做的步骤:
cv::Mat undistorted = cv::Mat(cvSize(maxWidth,maxHeight), CV_8UC1);
cv::Mat original = [MatStructure convertUIImageToMat:adjustedImage];
cv::warpPerspective(original, undistorted, cv::getPerspectiveTransform(src, dst), cvSize(maxWidth, maxHeight));
original.release();
adjustedImage = [MatStructure convertMatToUIImage:undistorted];
undistorted.release();
问题是可见的,当我将我的垫子转换为uiimage时,内存上升到400 mb,并且在每个周期上升。
+ (UIImage *) convertMatToUIImage: (cv::Mat) cvMat {
NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize() * cvMat.total()];
CGColorSpaceRef colorSpace;
if (cvMat.elemSize() == 1) {
colorSpace = CGColorSpaceCreateDeviceGray();
} else {
colorSpace = CGColorSpaceCreateDeviceRGB();
}
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef) data);
CGBitmapInfo bmInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
CGImageRef imageRef = CGImageCreate(cvMat.cols, // width
cvMat.rows, // height
8, // bits per component
8 * cvMat.elemSize(), // bits per pixel
cvMat.step.p[0], // bytesPerRow
colorSpace, // colorspace
bmInfo, // bitmap info
provider, // CGDataProviderRef
NULL, // decode
false, // should interpolate
kCGRenderingIntentDefault // intent
);
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
cvMat.release(); // this line is optional.
return image;
}
我见过许多类似的代码,但每个例子都是这样的。
我相信问题在(__bridge CFDataRef)
并且ARC
无法清除此数据,如果我将尝试CFRelease((__bridge CFDataRef)data)
而不会发生崩溃,因为程序将搜索已分配的内存并且它将被释放所以它会崩溃。
我正在使用openCV3
并尝试了他们的方法MatToUIImage
但问题仍然存在,在leaks
探查器上根本没有泄漏,内存中最昂贵的任务是{{1 }}
我整天都在阅读它,但实际上还找不到任何有用的解决方案。
目前我正在使用convertMatToUIImage
继承swift 3.0
,并使用class XXX
类来裁剪某些内容,而不是返回objC
。在UIImage
我正在分配这个继承的类属性nil,但问题仍然存在。我认为deinit
正在重复内存,就像我在创建dataWithBytes
后开始16MB
一样它将是NSData
..
如果你能就这个问题提出有用的线索,我将很高兴看到它们。谢谢你的帮助
答案 0 :(得分:0)
在处理这个问题超过三天后,我不得不重写功能,它100%工作,我已经在五个不同的设备上测试过。
CFRelease
,Free(
)和@autoreleasepool
根本没有帮助我,我实施了这个:
data = UIImageJPEGRepresentation([[UIImage alloc] initWithCGImage:imageRef], 0.2f); // because images are 30MB and up
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:@"MyFile.jpeg"];
[data writeToFile:appFile atomically:NO];
data = nil;
在此解决方案之后一切正常。所以我抓住UIImage
并转换为NSData
,之后我们应该将其保存到本地目录,剩下的就是从directory
读取数据。希望这个帖子有一天会帮助别人。