Río*_*ire 14 iphone objective-c avfoundation uiimage ios
从剖析中Instruments
我了解到,我将图像保存到磁盘的方式导致了内存峰值~60MB
.这导致应用程序发出low memory warnings
,(不一致)导致iPhone4S
运行中的崩溃iOS7
.
我需要最有效的方法将图像保存到磁盘.
我目前正在使用此代码
+ (void)saveImage:(UIImage *)image withName:(NSString *)name {
NSData *data = UIImageJPEGRepresentation(image, 1.0);
DLog(@"*** SIZE *** : Saving file of size %lu", (unsigned long)[data length]);
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:name];
[fileManager createFileAtPath:fullPath contents:data attributes:nil];
}
Run Code Online (Sandbox Code Playgroud)
笔记:
减少compressionQuality
参数值UIImageJPEGRepresentation
不会显着降低内存峰值.例如
compressionQuality = 0.8
,3MB
通过100
写入平均减少内存峰值.但是,它确实减少了磁盘上数据的大小(显然),但这对我没有帮助.
UIImagePNGRepresentation
取而代之的UIImageJPEGRepresentation
是更糟糕的.速度较慢,导致峰值较高.
难道这种做法有ImageIO
会更有效?如果是这样的话?
如果有人有任何建议,那将是伟大的.谢谢
编辑:
关于以下问题中概述的一些要点的说明.
a)虽然我正在保存多个图像,但我没有将它们保存在循环中.我做了一些阅读和测试,发现自动释放池不会帮助我.
b)每张照片的尺寸不是60Mb.他们是在iPhone 4S上拍摄的照片.
考虑到这一点,我回过头来试图克服我认为的问题; 这条线NSData *data = UIImageJPEGRepresentation(image, 1.0);
.
导致崩溃的内存峰值可以在下面的屏幕截图中看到.他们对应于UIImageJPEGRepresentation
被召唤的时间.我也跑了Time Profiler
,System Usage
它指向了同一个方向.
长话短说,我转过来AVFoundation
拍摄照片图像数据
photoData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
返回一个类型的对象NSData
,然后我使用它作为使用NSFileManager写入的数据.
这样可以完全消除内存中的尖峰.
即
[self saveImageWithData:photoData];
Run Code Online (Sandbox Code Playgroud)
哪里
+ (void)saveImageWithData:(NSData *)imageData withName:(NSString *)name {
NSData *data = imageData;
DLog(@"*** SIZE *** : Saving file of size %lu", (unsigned long)[data length]);
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:name];
[fileManager createFileAtPath:fullPath contents:data attributes:nil];
}
Run Code Online (Sandbox Code Playgroud)
PS:我没有把这个作为问题的答案,因为人们觉得它没有回答标题"在iPhone上将照片保存到磁盘的最有效的内存方式吗?".但是,如果达成共识的话应该是我可以更新它.
谢谢.
您的图像实际上每张压缩为 60MB 吗?如果是的话,如果您想将它们保存为单个 JPEG 文件,您无能为力。您可以尝试将它们渲染为较小的图像,或者平铺它们并将它们保存到单独的文件中。
我不指望你的 ImageIO 代码片段能改进任何东西。如果有两行修复,那么UIImageJPEGRepresentation
将在内部使用它。
但我敢打赌,您不会从单个图像中获得 60MB 的大小。我敢打赌,您可以从循环保存的多个图像中获得 60MB 的空间。如果是这样的话,那么您可能可以做一些事情。@autoreleasepool{}
在循环内放入一个。您很可能正在累积自动释放的对象,这会导致峰值。在循环内添加一个池可以使其排水。