Flex: map unrealized UIComponent to BitmapData?

What is the best way to render a UIComponent that has not been added to the scene? (I use UIComponents as renders for objects and want to display new copies for exporting images, filtering, etc.)

The two strategies I've seen / used so far include implementing a component so that it invokes all life cycle methods:

  • Add the component to Application.application , render with BitmapData.draw (), remove the component. This is similar to what I saw for printing unrealized components.

  • Add the component to the popup window, visualize using BitmapData.draw (), cancel the popup window after the rendering is complete.

I believe that both of them simply rely on a user interface that is not updated while the current thread / event is being executed, although (1) can also rely on a component that is implemented out of sight.

Is there a better way?

+6
flex actionscript actionscript-3
source share
4 answers

What I have used in the past with great success is the following:

  • Create a new instance of your component
  • Add Event Listener for FlexEvent.CREATION_COMPLETE
  • Set visible = false on the component
  • Add component as a child of the main application
  • When a component is created, the event listener function will be called. The rest of the logic should be placed / called from the event listener function.
  • Remove the event listener that you added in step 2.
  • Use ImageSnapshot.captureImage () or captureBitmapData () to capture a visual representation of the component.
  • Remove component from main application
  • Process the image data as you need.

I used this to take snapshots of the various components of a Flex chart for use in server side PDFs. After getting BitmapData, I use the PNGEncoder or JPEGEncoder classes to compress the data, then encode them in Base64 before uploading it to the server.

+10
source share

I am sure that you can use the draw () method in BitmapData without your component in the DisplayList.

For example, use it when I need to change images loaded using the Loader class. In the initialization handler, I create an instance of BitmapData and draw a Bitmap from the loadInfo.content property, then copyPixels () or whatever I need to change the loaded image

+2
source share

Most of the UIComponent layout can be context bound. This is especially true for many of its derivatives (for example, HBox), since the fluidity of the layout is tied to it by the size of the parent and the number of brothers and sisters sharing the space of their parents.

In addition, Flex can be a real pain for visual updates. Often, critical rendering functions are not performed synchronously ... there are callLater , callLater2 and other hacker approaches that can cope with the callLater2 properties of the UIComponents layout of the main headache. Even calling validateNow or updateDisplayList can guarantee that the layout is in the current frame (instead of several frames in the future).

I suggest you use UIComponent best and try to use Sprite or something else.

Your approach, to attach it but make it invisible ( alpha = 0 , mouseEnabled = false , mouseChildren = false ), is worthy. You must listen to the FlexEvent.CREATION_COMPLETE callback before making sure it is laid out correctly. Then you can bitmapData.draw it, and then remove it from the scene. If you must use UIComponents, then I do not know a better way.

+1
source share

You can call the lifecycle function manually before using BitmapData.draw (). Follow these steps.

  • createChildren ().
  • commitProperties ().
  • updateDisplayList ().
  • bmd.draw ().

The first 2 steps are not 100% needed, you can put all the codes in updateDisplayList (). Since you are calling the function manually, you don’t have to worry that the Flex Framework calls it many times.

0
source share

All Articles