7

私はそのような画像を取得するために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 秒かかります。そして、これは絶対に長すぎます。

質問: この画像保存プロセスをスピードアップするにはどうすればよいですか? または、これに対するより良い解決策はありますか?

更新: 両方のソリューションで最もパフォーマンスが向上するのは、画像を PNG ではなく JPEG 形式で保存することです。そのため、ソリューション 1 は に置き換えられUIImagePNGRepresentationましたUIImageJPEGRepresentation。ソリューション 2 は に置き換えkUTTypePNGましたkUTTypeJPEG

また、2 番目のソリューションは、最初のソリューションよりもメモリ効率が高いことにも注意してください。

4

3 に答える 3

9

代わりに生データをコピーすることもできます。
これには、ファイルを再エンコードしない、ファイルを大きくしない、追加の圧縮によって品質を失わない、ファイル内のメタデータを保持するという利点があります。また、可能な限り最速の方法である必要があります。あなたが持っていると
仮定して、それを保存します。 エラー処理も追加する必要があります。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];
}
于 2012-11-23T14:21:48.670 に答える
2

これは、PNG 圧縮の処理が遅く、特にフルサイズの写真の場合、iPhone のプロセッサで時間がかかるためです。

于 2012-02-13T12:51:47.400 に答える
1

プロセスを高速化する方法はありませんが、可能な解決策はスレッドを使用することです。これにより、メインスレッドをブロックせず、ユーザーにより良いエクスペリエンスを提供できます。

dispatch_queue_t dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(dispatchQueue, ^(void) {
    // Your code here
});
于 2012-05-26T14:47:02.407 に答える