大多数内存有效的方法将照片保存到iPhone上的磁盘?

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)

笔记:

  1. 减少compressionQuality参数值UIImageJPEGRepresentation不会显着降低内存峰值.例如 compressionQuality = 0.8,3MB通过100写入平均减少内存峰值.但是,它确实减少了磁盘上数据的大小(显然),但这对我没有帮助.

  2. 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上将照片保存到磁盘的最有效的内存方式吗?".但是,如果达成共识的话应该是我可以更新它.

谢谢.

Rob*_*ier 2

您的图像实际上每张压缩为 60MB 吗?如果是的话,如果您想将它们保存为单个 JPEG 文件,您无能为力。您可以尝试将它们渲染为较小的图像,或者平铺它们并将它们保存到单独的文件中。

我不指望你的 ImageIO 代码片段能改进任何东西。如果有两行修复,那么UIImageJPEGRepresentation将在内部使用它。

但我敢打赌,您不会从单个图像中获得 60MB 的大小。我敢打赌,您可以从循环保存的多个图像中获得 60MB 的空间。如果是这样的话,那么您可能可以做一些事情。@autoreleasepool{}在循环内放入一个。您很可能正在累积自动释放的对象,这会导致峰值。在循环内添加一个池可以使其排水。