【问题标题】:How to save ALAsset image to disk fast on iOS?如何在 iOS 上快速将 ALAsset 图像保存到磁盘?
【发布时间】:2012-03-04 20:45:22
【问题描述】:

我正在使用 ALAsset 来检索这样的图像:

[[asset defaultRepresentation] fullResolutionImage]]

这会返回 CGImageRef,我想尽快将其保存到磁盘...

解决方案 1:

UIImage *currentImage = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]];
NSData *currentImageData = UIImagePNGRepresentation(currentImage);
[currentImageData writeToFile:filePath atomically:YES];

解决方案 2:

CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:filePath];
CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, NULL);
CGImageDestinationAddImage(destination, [[asset defaultRepresentation] fullResolutionImage], nil);
CGImageDestinationFinalize(destination);

问题在于这两种方法在设备上的执行速度都非常慢。每张图片我需要大约 2 秒来执行此操作。这绝对是太长了。

问题:如何加快图像保存过程?或者也许有更好的解决方案?

更新: 这两种解决方案的最佳性能改进是将图像保存为 JPEG 格式而不是 PNG。 因此,对于解决方案 1,已将 UIImagePNGRepresentation 替换为 UIImageJPEGRepresentation。 对于解决方案 2,已将 kUTTypePNG 替换为 kUTTypeJPEG

另外值得注意的是,第二种解决方案比第一种解决方案更节省内存。

【问题讨论】:

    标签: ios image save disk alasset


    【解决方案1】:

    您可以直接复制原始数据。
    这具有不重新编码文件、不使文件变大、不因额外压缩而损失质量以及保留文件中的任何元数据的优点。 也应该是最快的方式。
    假设您有 theAssetfilepath 将其保存到。
    还应该添加错误处理。

    long long sizeOfRawDataInBytes = [[theAsset defaultRepresentation] size];
    NSMutableData* rawData = [NSMutableData dataWithLength:(NSUInteger) sizeOfRawDataInBytes];
    void* bufferPointer = [rawData mutableBytes];
    NSError* error=nil;
    [[theAsset defaultRepresentation] getBytes:bufferPointer 
                                    fromOffset:0
                                        length:sizeOfRawDataInBytes
                                         error:&error];
    if (error) 
    {
        NSLog(@"Getting bytes failed with error: %@",error);
    }
    else 
    {
        [rawData writeToFile:filepath 
                  atomically:YES];
    }
    

    【讨论】:

    • 这样的问题是图片的方向信息丢失了
    【解决方案2】:

    这是因为 PNG 压缩过程很慢,并且在 iPhone 的处理器上需要一段时间,尤其是对于全尺寸摄影。

    【讨论】:

    • 我明白这一点。但是有没有其他更有效的方法来做到这一点?我不需要PNG。其实任何格式都可以。我只需要将原始图像从 ALAsset 复制到我的自定义文件夹...?谢谢
    • 我刚刚尝试了 JPEG 表示 - 它比 PNG 表示快了大约一半(仍然大约 1 秒)。这要好得多。但仍然不是我所期望的。还有别的事吗?我发布的两种解决方案之间的区别是什么?两者相比有什么优势吗?
    • 最耗时的操作是图像的压缩,所以这两种方法应该花费大约相同的时间。如果你只需要一张图片,你可以保存 CGImage 的字节,然后加载它们,这样就可以省略压缩。
    • 不,我将保存多个图像。你有什么例子吗?另外,我不需要压缩。原图没问题...
    • 我没有例子,例如看这个问题:stackoverflow.com/questions/1579631/…
    【解决方案3】:

    没有这样的方法可以加快进程,但一个可能的解决方案是使用线程,这样你就不会阻塞主线程,你会为用户提供更好的体验:

    dispatch_queue_t dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(dispatchQueue, ^(void) {
        // Your code here
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      • 1970-01-01
      • 1970-01-01
      • 2014-05-02
      • 1970-01-01
      • 2011-01-17
      相关资源
      最近更新 更多