1

UIImageに変換したいEAGLViewがあります。私はここに投稿された解決策でこれを行うことができます:

EAGLViewからUIImageを取得するにはどうすればよいですか?

ただし、これを達成できるのは、EAGLViewの作成とUIImageの作成の間に少し時間が経過した場合のみです。

EAGLViewを作成し、その直後にUIImageViewを作成するこのコードは、機能しません。

EAGLView *EAGLphoto = [[EAGLView alloc] initWithImage:photo.workAreaImage];

[theWorkArea.photoArea1 addSubview:EAGLphoto];

//I put a glfinish() here but it didn't help

UIImageView *photoView = [[UIImageView alloc] initWithImage:[self glToUIImage]];
//glToUIImage is taken from the link above

[theWorkArea.photoArea2 addSubview:photoView];

EAGLViewの作成が完了する前に、UIImageViewが作成されようとしていると思います。glfinish()を間に入れようとしましたが、何もしませんでした。コードを実行すると、EAGLViewは正常に表示されますが、UIImageViewは黒で表示されます。

ただし、上記のコードのこの変更バージョンは機能します。

EAGLView *EAGLphoto = [[EAGLView alloc] initWithImage:photo.workAreaImage];

[theWorkArea.photoArea1 addSubview:EAGLphoto];

[self performSelector:@selector(getUIImage) withObject:nil afterDelay:0.1];

- (void)getUIImage {

    UIImageView *photoView = [[UIImageView alloc] initWithImage:[self glToUIImage]];
    //glToUIImage is taken from the link above

    [theWorkArea.photoArea2 addSubview:photoView];

}

glfinish()を間違って使用していますか?私のハックよりも良い方法はありますか?

4

1 に答える 1

0

通常、UIKitオブジェクトを即座に更新するのではなく、目に見える変更を加えると、将来それらの変更を行うためにフラグを立てるだけで、次にメインスレッドを放棄するときに(runloopに戻ることによって)変更のセット全体をバッチとして実行します。これは、実装の機能の誤りや失敗ではありません。実際には、通常、暗黙的に期待するものであり、次のようなコードを記述できる理由です。

view.frame = someNewFrame;
view.someOtherProperty = someOtherValue;

また、他の変更を採用する前に、ビューが目に見えて新しいフレームを採用することがよくあることを心配する必要はありません。原則として、ビューに対して行うことはアトミックに見えるようにする必要があります。

ここにあるように、要求した変更がまだ有効になっていないという状況に遭遇することがあります。frame上記の例では新しい値をsomeOtherProperty返すので、変更がすぐに有効になるかどうかは気になりませんが、観察にperformSelector:withObject:afterDelay:よると、変更がふりをしない状況に遭遇した可能性があります。すぐに。

EAGLViewこれは実際にはUIKitの機能ではないため、診断が困難です。それCAEAGLLayerが構築されているのは、 AppleがさまざまなサンプルプロジェクトでEAGLView構築されたカスタムUIViewサブクラスに採用した名前です。CAEAGLLayer例全体のインターフェイスや実装について一貫性はありませんがEAGLView、おそらくOpenGLフレームバッファオブジェクト(つまり、OpenGLがピクセルに関連する数値を格納するために使用するもの)を作成していると思います。glReadPixels動作する)自分自身をレイアウトするように求められた場合にのみ、UIKitがそうするように要求するまで自分自身をレイアウトしません。これは、runloopにドロップアウトするまではありません。

その診断はあなたが持っているのコードをチェックすることによって確認することができEAGLViewます。glGenFramebuffersの結果としてトリガーされるようなものへの呼び出しがたくさんある場合layoutSubviewsdrawRectまたは関連するものによって直接呼び出されない他のメソッドがある場合init、それはそれを証明します。

その診断が正しいと仮定すると、適応することができますが、EAGLViewおそらく最善の解決策は、に固執することだと思いますperformSelector:withObject:afterDelay:0。これは競合状態ではないため、解決策が少し不安定になったり信頼性が低下したりすることはありません。「EAGLViewを使用できることがわかっているので、UIKitにこれらのすべての指示に追いつくようにしましょう。意味のある状態になり、それから私のものを続けてください。」

于 2011-08-14T02:00:50.283 に答える