3

以下のコードを使用して、UIView を UIImage に変換しようとしています。

+ (UIImage *) imageWithView:(UIView *)view{
     float scale = 1.0f;
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, scale);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage* img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    view.layer.contents = nil;
    return img;
}

このコードには 2 つの問題があります。

1. このコードをバックグラウンド スレッド (!mainThread) で実行すると

バックグラウンド スレッドで renderInContext が呼び出されると、メモリ リークの問題が発生しました。

2.このコードをメインスレッドで実行すると

メモリ リークはありませんが、iPad 3 では、UIView からイメージを作成しているときにパフォーマンスの問題に直面しています (このメソッドが呼び出されると UI がハングします)。この関数を 1 秒間に 5 回以上呼び出す必要があるため、UI がハングしてユーザー エクスペリエンスが非常に悪くなります。

ここで何か間違ったことをしている場合は、私を導いてください。

4

2 に答える 2

8

問題 1 は、スレッドセーフではないという事実に関連していると思います。UIKitその使用はあらゆる種類の副作用につながります。

あなたが説明しているようなパフォーマンスの問題がある場合、私が見る唯一の方法は、セカンダリ スレッドで (UIKit ではなく) CoreGraphics を直接使用することです。

手始めに、次のようなことを試してみてください。

size_t width = view.bounds.size.width;
size_t height = view.bounds.size.height;

unsigned char *imageBuffer = (unsigned char *)malloc(width*height*4);
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();

CGContextRef imageContext =
    CGBitmapContextCreate(imageBuffer, width, height, 8, width*4, colourSpace,
              kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);

CGColorSpaceRelease(colourSpace);

[view.layer renderInContext:imageContext];

CGImageRef outputImage = CGBitmapContextCreateImage(imageContext);

CGImageRelease(outputImage);
CGContextRelease(imageContext);
free(imageBuffer);

ご覧のとおり、これは方法よりもかなり複雑ですがUIKit、セカンダリ スレッドで実行できます (outputImage表示されていない UI スレッドに戻す方法が見つかった場合)。

于 2012-10-11T16:22:15.740 に答える
2

メインスレッドでこれが発生しました( によるメモリリークrenderInContext) 。何百ものオフスクリーン ビューをループしてオブジェクトにレンダリングし、PNG ファイルとして保存していました。私にとって問題を解決したのは、ループの内臓をブロックでラップすることでした:UIImage@autoreleasepool

壊れた:

for (...) {
   ...render layer in context...
   ...save image to disk...
}

作品:

for (...) {
   @autoreleasepool {
      ...render layer in context...
      ...save image to disk...
   }
}

理にかなっていますよね?

于 2013-08-30T05:27:52.700 に答える