Native Rasterizer (bitmap slicing) and more by Thibault Imbert

Do you remember Banana Slice ? I already blogged about native rasterizing (bitmap slicing) in the Flash Player (here), but I realize I did not log a feature request in the Adobe bugs jira. I would love to see a native rasterizer in the Flash Player, which would rasterize or caches each frame of a MovieClip in order to get an animated bitmap to get nice rendering performance improvements when the MovieClip is played :

We could have a rasterize property to dynamically rasterize a MovieClip as bitmap frames to get super performance improvements :

MovieClip.rasterize = true

The MovieClip could contain a BitmapSequence extending InteractiveObject allowing you to access each bitmap frames. In some cases, this would consume more memory, but the developer should be able to choose between more memory usage and nice rendering improvements, just like cacheAsBitmap where you have to counter balance the pros and the cons. This feature could also be used by a designer or animator in the Flash Pro authoring tool. If you like the idea, please vote for this feature request :

http://bugs.adobe.com/jira/browse/FP-3945

When trying to create your own rasterizing engine, you may come into the situation where you want to know the real width and height of a DisplayObject having filters applied, like a BlurFilter for instance, in order to create each BitmapData frame, the following image illustrates the idea :

The code below retrieves the width and height of the MovieClip with getBounds, you notice that you got the same results for both MovieClips :

// outputs : (x=46.5, y=154.45, w=198, h=117.94999999999999)
trace( mc1.getBounds ( this ) );
// outputs : (x=299.5, y=153.45, w=198, h=117.94999999999999)
trace( mc2.getBounds ( this ) );

Same with the width and height properties. Of course you can calculate an approximation based on the filter properties and deduce an approximate width or height. You can also iterate through the filters property create a BitmapData object then use the generateFilterRect() method to evaluate the pixels dissolution value and estimate the final width, but well, that's not a really smooth way to achieve that. Having a DisplayObject.getFiltersRect() and DisplayObject.generateFilterRect() methods would be sweet. If you like the idea, please vote for this feature request :

http://bugs.adobe.com/jira/browse/FP-3948

Comments (10)

  1. Claus Wahlers wrote::

    As a workaround for a native Rasterizer, you could use as3swf to do exactly what you are looking for, at runtime (if i understand you correctly).

    http://github.com/claus/as3swf

    Thursday, February 18, 2010 at 2:09 pm #
  2. Claus Wahlers wrote::

    Having said that, i think it wouldn’t make a good, generic native FP feature, first of all it might not be feasible (imagine deeply nested movieclips, even possibly containing video and such) and users might shoot themselves in the foot (movieclips with many many frames: memory.. bitmaps are big, memory wise).

    but, well, as3swf does provide everything needed for a non-native solution (shape export, creation of swfs at runtime)

    Thursday, February 18, 2010 at 2:46 pm #
  3. Bart wrote::

    I like your idea: it would be very usefull to have animation rasterizing as a default feature.

    But im not sure if it’s a good idea to make this an instance-property. That would imply Flash will rasterize the state of this instance only, so if you’d have like 10 instances on screen you’d have to set rasterize to true on every instance and Flash would create 10 times as many rendered frames (=memory would explode and playback speed would still suck).

    So we’ll need a system that will render a single animation and re-use it’s frames for each instance of that animation. But that approach will introduce a problem if you’d modify the first instance of that animation (by inserting content in a nested holder or whatever): what will happen? Will all instances be modified or should Flash keep track of modifications and do some clever instance-specific rerendering?

    At the office we build a quite extensive run-time rasterizer that operates on Class-definiton level: you’d specifiy the Linkage-ClassName you’d want to have a rasterized version of, and together with some other settings it will be stored under an String-allias so you can render different versions of the same clip-definition. Every rendered definition will then share it’s frames over all it’s display-instances (easy since multiple Bitmap’s can share a single BitmapData).

    The DisplayObject.getFiltersRect() idea is so awesome im creating a jira-login just for that! ( when building our own renderer it drove us so crazy we settled for a manual ‘frame-padding’ parameter).

    Thursday, February 18, 2010 at 3:06 pm #
  4. Thibault Imbert wrote::

    Hi Claus,

    First, congrats for AS3SWF, it is an awesome project. I did not think about it concerning rasterizing but yes with your export API that would work smoothly. If doable in AS3, that could be done natively by the player which would make such a feature easier for non-developers or interactive designers. But, yes, there would be some requirements to have this feature working. I agree with the fact that some guidelines would be necessary so that people really understand what is possible and what is not concerning nested animations and do not overuse it, just like cacheABitmap or when using the BitmapData API.

    Hi Bart,

    Yes, I agree with your concern related to caching the frames and reuse them through the instances of the same symbol. This is something that is doable today when making a custom rasterizing engine, so maybe this could be handled also natively. I would love to see that for cacheAsBitmap, to reuse the same bitmap in memory for all the instances. To bypass that, I use a manual bitmap caching approach : http://www.bytearray.org/?p=290

    Another implementation could be calling a rasterize() method which could return a BitmapDataSequence object that you could use through a Bitmap.bitmapDataSequence property. This way you would be able to have a single BitmapDataSequence object and reuse it through multiple Bitmap instances. That BitmapDataSequence could have methods to control it (frameRate, loop, etc.) What do you think ?

    Cool you like, the getFiltersRect() idea, I created a jira request for that, make sure to vote for it ! :)

    best,

    Thibault

    Thursday, February 18, 2010 at 4:17 pm #
  5. Jerome wrote::

    A cool option for DisplayObject.getFiltersRect(filterIndex:int = -1):Rectangle

    getFiltersRect(-1) // all filters
    getFiltersRect(0) // first filter
    getFiltersRect(1) // second filter

    Thursday, February 18, 2010 at 4:40 pm #
  6. Bart wrote::

    I’m totaly in favor of a MovieClip.getRasterized():BitmapDataSequence kinda approach, implemented in such a way that you get the BitmapDataSequence of the state of that specific instance (with added or modified content). Then you could store that somewhere and retrieve it’s reference to display in a BitmapSequenceDisplay-type of DisplayObject.

    I dont think BitmapDataSequence should have the playback methods, there should be a split between the rendering result (BitmapDataSequence) and the displayObject instances (BitmapDataSequenceDisplay or something like that).

    The BitmapDataSequenceDisplay should have the standard MovieClip gotoAndStop/play/etc playback methods (maybe unified with MovieClip in a interface or a clever sub-class), so you can reuse the frame-labels.

    MovieClip.rasterized = true could be a magic shortcut that rasterizes this specific instance and swaps it in the timeline it’s currently playing in (like your original proposal).

    Thursday, February 18, 2010 at 4:54 pm #
  7. Thibault Imbert wrote::

    Hi Bart,

    Yes, I see. You would like to keep the same distinction as with Bitmap and BitmapData representing only raw pixels. You would see the controls on a BitmapDataSequenceDisplay like class. Yes rasterize = true could be a shortcut to implicitly tell the player to place the BitmapDataSequence inside the existing instance.

    Thibault

    Thursday, February 18, 2010 at 5:09 pm #
  8. Jloa wrote::

    Hi, Thibault.
    Yeap, i’m surely for this feature and i’ve voted for it (which obvious).
    But, still i’ve noticed that the “redraw” engine actually sees the real bounds of the objects.
    Here’s a screenshot revealing that http://img522.imageshack.us/img522/2862/51941629.png

    Friday, February 19, 2010 at 1:26 pm #
  9. Vlakken wrote::

    I just advance the timeline and take bitmapdata screenshots of each frame before the site starts.

    I then just play them back onEnterFrame when I need them.

    Sunday, March 28, 2010 at 12:48 am #
  10. Wolfgang wrote::

    I just ran into this exact issue in 2012, 2 years after the thread was created.

    Has there been any progress? Does a solution exist now?

    Monday, August 13, 2012 at 5:42 pm #