Flex: визуализировать нереализованный UIComponent для BitmapData? - PullRequest
6 голосов
/ 21 августа 2009

Каков наилучший способ рендеринга на UIComponent, который не был добавлен на сцену? (Я использую UIComponents в качестве средств визуализации объектов и хочу рендерить новые копии для экспорта изображений, фильтрации и т. Д.)

Две стратегии, которые я видел / использовал до сих пор, включают реализацию компонента, чтобы он вызывал все методы жизненного цикла:

  1. Добавить компонент в Application.application, выполнить рендеринг с помощью BitmapData.draw (), удалить компонент. Это похоже на то, что я видел для печати нереализованных компонентов.

  2. Добавить компонент во всплывающее окно, выполнить рендеринг с помощью BitmapData.draw (), закрыть всплывающее окно после завершения рендеринга.

Я полагаю, что оба они просто полагаются на то, что пользовательский интерфейс не обновляется во время выполнения текущего потока / события, хотя (1) может также полагаться на компонент, реализуемый вне поля зрения.

Есть ли лучший способ?

Ответы [ 4 ]

10 голосов
/ 26 августа 2009

То, что я использовал в прошлом с большим успехом, таково:

  1. Создайте новый экземпляр вашего компонента
  2. Добавить прослушиватель событий для FlexEvent.CREATION_COMPLETE
  3. Установить видимый = ложь для компонента
  4. Добавить компонент как дочерний элемент основного приложения
  5. При создании компонента будет вызвана функция прослушивателя событий. Остальная часть логики должна быть введена / вызвана из вашей функции прослушивания событий
  6. Удалите прослушиватель событий, добавленный на шаге № 2.
  7. Используйте ImageSnapshot.captureImage () или captureBitmapData () для захвата визуального представления компонента.
  8. Удалить компонент из основного приложения
  9. Обрабатывайте данные изображения так, как вам нужно.

Я использовал это для создания снимков различных компонентов диаграмм Flex для использования в PDF-файлах, созданных на стороне сервера. После получения BitmapData я использую классы PNGEncoder или JPEGEncoder для сжатия данных, а затем кодирую их в Base64 перед загрузкой на сервер.

2 голосов
/ 21 августа 2009

Я уверен, что вы можете использовать метод draw () в BitmapData, не добавляя ваш компонент в DisplayList.

Например, используйте его, когда мне нужно изменить изображения, которые я загружаю с помощью класса загрузчика. В обработчике init я создаю экземпляр BitmapData и рисую Bitmap из свойства loadInfo.content, затем copyPixels () или все, что мне нужно для изменения загруженного изображения

1 голос
/ 23 августа 2009

Большая часть макета UIComponent может быть привязана к его контексту. Это особенно верно для многих его производных (например, HBox), поскольку текучесть макета привязана к размеру его родителя и количеству братьев и сестер, разделяющих пространство его родителей.

Кроме того, Flex может быть реальной болью, чтобы получить визуальное обновление. Часто критические функции рендеринга не выполняются синхронно ... существуют callLater, callLater2 и другие хакерские подходы, которые делают работу с автоматическими магическими свойствами макета UIComponents главной головной болью. Даже вызов validateNow или updateDisplayList не может гарантировать, что макет будет правильным для текущего кадра (вместо нескольких кадров в будущем).

Я предлагаю лучшее, что вы можете сделать, это не использовать UIComponent и попробовать использовать Sprite или другой.

Ваш подход прикрепить его, но сделать его невидимым (alpha = 0, mouseEnabled = false, mouseChildren = false) вполне приличный. Вы должны прослушать обратный вызов FlexEvent.CREATION_COMPLETE, прежде чем будете уверены, что он правильно спланирован. Затем вы можете bitmapData.draw это и затем удалить его со сцены. Если вы должны использовать UIComponents, то я не знаю лучшего способа.

0 голосов
/ 07 августа 2013

Вы можете вызвать функцию жизненного цикла вручную перед использованием BitmapData.draw (). Сделайте следующее.

  1. createChildren ().
  2. commitProperties ().
  3. updateDisplayList ().
  4. bmd.draw ().

Первые 2 шага не обязательны на 100%, вы можете поместить все коды в updateDisplayList () Поскольку вы вызываете функцию вручную, вам не нужно беспокоиться о том, что Flex Framework ее вызывает много раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...