13

ビュー全体をレンダリングしてトリミングする以外に、UIViewのごく一部を画像にレンダリングする良い方法がないことを私はよく知っています。(結果の画像が巨大なiPad 3のようなものでは非常に高価です)。renderInContextメソッドの説明については、ここを参照してください(代替手段はありません)。

レンダリングしたいビューの部分を事前に決定することはできません。つまり、小さなセクションのビュー階層を独自のUIView(したがってCALayer)に設定することはできません。

私のアイデア...

アイデアはありましたが、成功するためには方向性が必要です。UIView(またはCALayer)で、次の行に沿ってメソッドを追加するカテゴリを作成するとどうなりますか?

[UIView renderSubframe:(CGFrame)frame];

どのように?さて、サブフレームサイズのダミービューを作成すれば、一時的にビューをシフトできると思います。次に、ダミービューのレイヤーがrenderInContext:を呼び出すことができるため、ビューを効率的かつ高速に取得できます。

それで...

私は実際にはCALayer/Quartzコアのものにそれほど精通していません...これは機能する可能性がありますか?そうでない場合、同じことを達成できる別の方法は何ですか?同じ結果を達成できる最も効率的な方法は何ですか(または他の誰かがすでにこの問題に直面して別の解決策を考え出している)?

4

2 に答える 2

28

最終的に書いたカテゴリーはこちらです。便利な CGAffineTransform のおかげで、最初に思ったほど難しくはありません。

#import "UIView+RenderSubframe.h"
#import <QuartzCore/QuartzCore.h>

@implementation UIView (RenderSubframe)

- (UIImage *) renderWithBounds:(CGRect)frame {

    CGSize imageSize = frame.size;

    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);
    CGContextRef c = UIGraphicsGetCurrentContext();

    CGContextConcatCTM(c, CGAffineTransformMakeTranslation(-frame.origin.x, -frame.origin.y));
    [self.layer renderInContext:c];

    UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return screenshot;

}

@end
于 2013-01-06T12:34:49.653 に答える
1

これを行うには、いくつかの異なる方法があります。

  1. CGContextClipToRectrenderInContextを呼び出す前に、コンテキストにを指定します。

  2. 使用する:

setNeedsDisplayInRect:

指定した長方形内の領域を更新が必要であることを示します。

     - (void)setNeedsDisplayInRect:(CGRect)theRect

これにより、指定された四角形でのみレンダリングが行われます。これがあなたの要件に従って機能するかどうかはわかりませんが。

最初のオプションはシームレスに機能するはずだと思います。

于 2013-01-05T11:16:13.537 に答える