2

ギャラリー付きのアプリを開発しています。すべての画像はデバイス ディスク (ドキュメント ディレクトリ) にありますが、スムーズに表示できません。

一部の画像は大きい (2000px * 2000px) ため、それらをバックグラウンド スレッドにロードし、縮小してからメイン スレッドに表示します。

ここに私の UIImageView 拡張機能があります:

@implementation UIImageView (BackgroundResize) 

- (void)localImageFromPath: (NSString *) path scaledTo: (CGSize) size {
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
    dispatch_async(queue, ^{
        //Load image
        NSData * imgData = [[NSData alloc] initWithContentsOfFile:path];
        UIImage * original = [[[UIImage alloc]  initWithData:imgData] autorelease];
        [imgData release];
        CGSize imgSize = original.size;
        float widthScale = size.width / imgSize.width;
        float heightScale = size.height / imgSize.height;
        float scaleFactor = widthScale;
        if (heightScale < scaleFactor) {
            scaleFactor = heightScale;
        }
        UIImage * result = nil;
        //Scale if necessary
        if (scaleFactor < 1.0) {
            result = [[UIImage alloc] initWithCGImage:original.CGImage scale:1/scaleFactor orientation:original.imageOrientation];
        } else {
            result = [original retain];
        }
        NSLog(@"Image prepeared on backgroud thread, update ui image on main..");
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"Begin updating image on main thread");
            self.image = result;
            [result release];
            [[NSNotificationCenter defaultCenter] postNotificationName:NTF_IMG_LOADED object:self];
            NSLog(@"Updated");
        });

    });
    dispatch_release(queue);

}
@end

コンソール出力では、すべてが完璧に見え、すべてのデバッグ文字列が 1 秒未満で表示されます (6 つの非常に大きな画像の場合)。ただし、UI はブロックされ、画像は 10 秒の遅延で表示されます。

iOS で大きなローカル画像を表示する正しいアプローチは何ですか?

アプリは iOS5+ 向けにビルドされています。

ありがとう、

4

1 に答える 1

2

実際に画像のサイズを変更しているわけではありません。スクリーン座標点に対する画像ピクセルの比率を設定するパラメーターscale-initWithCGImage:scale:基になるイメージには何もしません。CGContext縮小するには、実際に画像を a に描画する必要があります。

    //Load image
    UIImage * original = [[[UIImage alloc] initWithContentsOfFile:path] autorelease];

    CGSize imgSize = original.size;
    float widthScale = size.width / imgSize.width;
    float heightScale = size.height / imgSize.height;
    float scaleFactor = widthScale;
    if (heightScale < scaleFactor) {
        scaleFactor = heightScale;
    }

    UIImage * result = nil;
    //Scale if necessary
    if (scaleFactor < 1.0) {
        CGSize newSize = CGSizeMake(floorf(imgSize.width * scaleFactor),
                                    floorf(imgSize.height * scaleFactor));
        UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
        [original drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
        result = UIGraphicsGetImageFromCurrentImageContext();
        [result retain];
        UIGraphicsEndImageContext();
    } else {
        result = [original retain];
    }
于 2013-04-06T17:50:09.803 に答える