6


5

ステージに追加されていない「UIComponent」にレンダリングするための最良の方法は何ですか? (私はオブジェクトのレンダラーとしてUIComponentsを使用しています。画像のエクスポート、フィルタリングなどのために新しいコピーをレンダリングしたいと思います)

私が今まで見てきた/使用した2つの戦略には、すべてのライフサイクルメソッドを確実に呼び出すためのコンポーネントの実現が含まれます。

  1. コンポーネントを `Application.application`に追加し、BitmapData.draw()でレンダリングし、コンポーネントを削除します。 これは、未実現のコンポーネントを印刷するために行ったのと似ています。

  2. ポップアップウィンドウにコンポーネントを追加し、BitmapData.draw()でレンダリングし、レンダリングが完了したらポップアップを閉じます。

どちらも現在のスレッド/イベントの実行中にUIが更新されないことに依存しているにすぎないと考えています。

もっと良い方法はありますか?

4 Answer


10


私がこれまで多くの成功を収めてきたものは以下の通りです。

  1. コンポーネントの新しいインスタンスを作成します

  2. FlexEvent.CREATION_COMPLETEのイベントリスナーを追加します。

  3. コンポーネントにvisible = falseを設定します

  4. メインアプリケーションの子としてコンポーネントを追加します

  5. コンポーネントが作成されると、イベントリスナー関数が呼び出されます。 ロジックの残りの部分は、イベントリスナー関数に配置したり呼び出したりする必要があります。

  6. 手順2で追加したイベントリスナを削除します。

  7. ImageSnapshot.captureImage()またはcaptureBitmapData()を使用してコンポーネントの視覚的表現をキャプチャします。

  8. メインアプリケーションからコンポーネントを削除する

  9. 必要に応じて画像データを処理します。

私はこれを使用して、サーバーサイドで生成されたPDFで使用するためのさまざまなFlexチャートコンポーネントをスナップショットを作成しました。 BitmapDataを取得したら、PNGEncoderクラスまたはJPEGEncoderクラスを使用してデータを圧縮し、サーバーにアップロードする前にBase64でエンコードします。


2


コンポーネントをDisplayListに配置しなくても、BitmapDataのdraw()メソッドを使用できることは間違いありません。

例えば、Loaderクラスでロードした画像を修正する必要があるときにそれを使用します。 initハンドラでBitmapDataインスタンスを作成し、loadInfo.contentプロパティからBitmapを描画し、次にcopyPixels()またはロードした画像を変更するために必要なものをすべて設定します


1


それで `UIComponent`のレイアウトの多くはそれのコンテキストに結び付けることができます。 これは、その多くの派生物に特に当てはまります。 レイアウトの流動性は、その親のサイズとその親のスペースを共有する兄弟の数に関係しているので。

加えて、Flexは視覚的に更新するためには本当に苦労することがあります。 多くの場合、重要なレンダリング機能は同期的には行われません…​ callLater、` callLater2`、そして UIComponents`の自動魔法のレイアウトプロパティを扱うことを主な頭痛の種とする他のハックなアプローチがあります。 `validateNow`や updateDisplayList`を呼び出さなくても(将来の数フレームではなく)現在のフレームでレイアウトが正しいことを保証できます。

UIComponentを使わずにSpriteなどを使ってみるのが一番良い方法です。

それをアタッチするが見えないようにするというアプローチ( alpha = 0、` mouseEnabled = false`、 mouseChildren = false)は適切です。 正しくレイアウトされていることを確認する前に、 `FlexEvent.CREATION_COMPLETE`コールバックを監視する必要があります。 それから、それを `bitmapData.draw`してからステージから削除することができます。 あなたがUIComponentsを使わなければならないならば、私はそれ以上の良い方法を知らない。


0


BitmapData.draw()を使用する前に、ライフサイクル関数を手動で呼び出すことができます。 以下をせよ。

  1. createChildren()

  2. commitProperties()

  3. updateDisplayList()

  4. bmd.draw()

最初の2つのステップは100%必要というわけではありません、あなたはupdateDisplayList()にすべてのコードを入れることができます。 関数を手動で呼び出すので、これがFlexフレームワークによって何度も呼び出されることを心配する必要はありません。