3

オブジェクトを使用するアプリがありUIImageます。この時点まで、次のようなものを使用して初期化された画像オブジェクトを使用してきました。

UIImage *image = [UIImage imageNamed:imageName];

私のアプリバンドルで画像を使用しています。を使用して、ユーザーがカメラまたはライブラリから画像を使用できるようにする機能を追加していますUIImagePickerController。これらの画像は、明らかに、アプリ バンドルに含めることはできないためUIImage、別の方法でオブジェクトを初期化します。

UIImage *image = [UIImage imageWithContentsOfFile:pathToFile];

これは、最初にアプリバンドル内の他のファイルと同様のサイズに画像のサイズを変更した後に行われます.ピクセル寸法と総バイト数の両方で、両方とも Jpeg 形式を使用します (興味深いことに、同じファイルサイズでも PNG ははるかに遅くなりました)。つまり、 が指すpathToFileファイルは、バンドル内の画像と同様のサイズのファイルです (ピクセルの寸法が一致し、圧縮が選択されたため、バイト数も同様でした)。

このアプリは、元の画像から小さな断片を作成するループを通過します。特に、この投稿には関係ありません。私の問題は、2 番目の方法で作成されたイメージを使用してループを通過すると、最初の方法で作成されたイメージを使用するよりもはるかに時間がかかることです。

最初の方法が画像をキャッシュすることは理解していますが、キャッシュの仕組みを理解していない限り、それは関係ないと思います。それが関連する要因である場合、2番目の方法にキャッシュを追加するにはどうすればよいですか?

ボトルネックの原因となっているコードの関連部分は次のとおりです。

[image drawInRect:self.imageSquare];

ここで、self は UIImageView のサブクラスです。そのプロパティ imageSquare は、CGRect何を描画するかを定義するだけです。この部分は、どちらの方法でも同じです。UIImageでは、同様のサイズのオブジェクトで 2 番目の方法が非常に遅いのはなぜでしょうか?

このプロセスを最適化するために別の方法でできることはありますか?

編集: バンドル内のイメージへのアクセスを変更しimageWithContentsOfFile、ループを実行する時間を約 4 秒から 1 分強に変更しました。imageNamedそのため、バンドルされていないファイルを使用して、キャッシングを行う方法を見つける必要があるようです。

4

1 に答える 1

1

UIImage imageNamed単に画像をキャッシュするだけではありません。非圧縮画像をキャッシュします。余分な時間が費やされたのは、ローカル ストレージから RAM への読み取りではなく、イメージの圧縮解除が原因でした。

解決策は、新しい圧縮されていないUIImageオブジェクトを作成し、それをコードの時間に敏感な部分に使用することでした。コードのそのセクションが完了すると、圧縮されていないオブジェクトは破棄されます。完全を期すために、別のスレッドUIImageのおかげで、圧縮されたオブジェクトから圧縮されていないオブジェクトを返すクラスメソッドのコピーを次に示します。これは、データが にあると仮定していることに注意してください。これは、オブジェクトに対して常に当てはまるとは限りません。CGImageUIImage

+(UIImage *)decompressedImage:(UIImage *)compressedImage
{
   CGImageRef originalImage = compressedImage.CGImage;
   CFDataRef imageData = CGDataProviderCopyData(
                         CGImageGetDataProvider(originalImage));
   CGDataProviderRef imageDataProvider = CGDataProviderCreateWithCFData(imageData);
   CFRelease(imageData);
   CGImageRef image = CGImageCreate(
                                CGImageGetWidth(originalImage),
                                CGImageGetHeight(originalImage),
                                CGImageGetBitsPerComponent(originalImage),
                                CGImageGetBitsPerPixel(originalImage),
                                CGImageGetBytesPerRow(originalImage),
                                CGImageGetColorSpace(originalImage),
                                CGImageGetBitmapInfo(originalImage),
                                imageDataProvider,
                                CGImageGetDecode(originalImage),
                                CGImageGetShouldInterpolate(originalImage),
                                CGImageGetRenderingIntent(originalImage));
   CGDataProviderRelease(imageDataProvider);
   UIImage *decompressedImage = [UIImage imageWithCGImage:image];
   CGImageRelease(image);
   return decompressedImage;
}
于 2013-09-12T18:25:52.467 に答える