03
Aug
07

Duplicating images using the Bitmap and BitmapData classes

In a previous post (Finding a pixel’s color value using the Bitmap classes and getPixel()) we looked at copying an image so we could build a simple color-picker like app. In this post, we explore duplicating a loaded image and copying it into a TileList control. Each time you press the “Copy image” button, a new instance of the source image is created and added to the TileList control’s data provider.

As an added bonus, we also create a custom item renderer consisting of an HBox container, Image control, and a Label control.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/08/03/duplicating-images-using-the-bitmap-and-bitmapdata-classes/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;

            [Bindable]
            private var arrColl:ArrayCollection = new ArrayCollection();

            private function dupeImage(source:Image):void {
                var data:BitmapData = Bitmap(source.content).bitmapData;
                var bitmap:Bitmap = new Bitmap(data);

                arrColl.addItem({image:bitmap, label:"item #" + (arrColl.length + 1)});
            }
        ]]>
    </mx:Script>

    <mx:HBox>
        <mx:Panel title="Source image">
            <mx:HBox verticalAlign="middle" horizontalAlign="center" width="100%" height="100%">
                <mx:Image id="img1" source="assets/logo.png" />
            </mx:HBox>

            <mx:ControlBar>
                <mx:Button label="Copy image" click="dupeImage(img1)" />
            </mx:ControlBar>
        </mx:Panel>

        <mx:TileList id="tileList" dataProvider="{arrColl}" width="300" height="200" columnCount="4" verticalScrollPolicy="on">
            <mx:itemRenderer>
                <mx:Component>
                    <mx:VBox>
                        <mx:Image source="{data.image}" />
                        <mx:Label text="{data.label}" />
                    </mx:VBox>
                </mx:Component>
            </mx:itemRenderer>
        </mx:TileList>
    </mx:HBox>

</mx:Application>

View source is enabled in the following example.


15 Responses to “Duplicating images using the Bitmap and BitmapData classes”


  1. 1 li wenzhi Aug 3rd, 2007 at 9:57 pm

    Good sample of bitmap operation, thank your for sharing experience!

  2. 2 Anonymous Aug 4th, 2007 at 12:10 am

    Very nice! I wait for the next example.

  3. 3 Tushar Wadekar Aug 5th, 2007 at 10:23 pm

    Good one! Thanks.

    ~Tushar

  4. 4 techpop Aug 21st, 2007 at 10:40 pm

    This is a great example. How about taking it a step further. Is there a way to grab “stills” from a playing flv, let’s say it’s a basic photo slideshow and compare them so you can “detect” a scene change? So you can create some kind of interval/timer that runs every so often, take a bitmap “snapshot” of what is in the video display and keep comparing it to the previous shot. I’m wondering if there are any methods in the bitmap class that can help determine the pixel percentage difference (or something like that) between two images captured in this way.

  5. 5 peterd Aug 22nd, 2007 at 8:31 pm

    techpop,

    I think I have an example of grabbing video stills from an VideoDisplay control whenever it encounters a cuePoint event. Regardless, it should be fairly easy if you use the Timer class or maybe listen for the VideoDisplay control’s playheadUpdate event.

    As for bitmap compares, I haven’t used it personally, but the BitmapData class has a compare() function which compares two BitmapData objects (see the Flex 2.0.1 LiveDocs for BitmapData.compare()).

    Peter

  6. 6 judah Nov 8th, 2007 at 2:16 pm

    A couple questions. Why do you use the Bitmap class instead of an Image class? Also, is there any reason not to use the clone method?

    var image:Bitmap = new Bitmap(source.bitmapData.clone());
    
  7. 7 peterd Nov 8th, 2007 at 2:34 pm

    judah,

    No reasons, I think this was just the first approach that came to mind.

    Peter

  8. 8 jj Apr 4th, 2008 at 8:24 am

    I encountered problem with adding Images to TileList control, and it can be reproduced in your example as well - if you add about 30 copies of the bitmap, catch a scrollbar and start scrolling up and down intensively, after short while, bitmaps start disappearing from random tiles. Also, if i continue, i get this:

    ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
    at flash.display::DisplayObjectContainer/removeChild()
    at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::$removeChild()
    at mx.core::UIComponent/removeChild()
    at mx.controls::SWFLoader/load()
    at mx.controls::SWFLoader/commitProperties()
    at mx.core::UIComponent/validateProperties()
    at mx.managers::LayoutManager/validateClient()
    at mx.controls.listClasses::TileBase/getPreparedItemRenderer()
    at mx.controls.listClasses::TileBase/makeRowsAndColumns()
    at mx.controls.listClasses::TileBase/scrollVertically()
    at mx.controls.listClasses::TileBase/scrollHandler()
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()
    at mx.controls.scrollClasses::ScrollBar/http://www.adobe.com/2006/flex/mx/internal::dispatchScrollEvent()
    at mx.controls.scrollClasses::ScrollThumb/mouseMoveHandler()
    (I have 9,0,115,0 player)

    Do you know any workaround for this? The problem is with TileList and Image controls together, rather than in BitmapData, because when i set direct image address in source field, same problem appears.

    Thanks in advance

  9. 9 betehes May 8th, 2008 at 7:17 am

    There is a big bug that I’m not able to fix…

    If I fill the TileList with enough objects to make the scrolling button to appear and if I scroll, the images will disappear…

    Am I the only one to have this problem ?

    Is there a way to fix it ?

    Thanks in advance.

  10. 10 martin May 21st, 2008 at 5:39 am

    @betehes:

    i’m having the exact same problem, very annoying, seems to be a bug in flex for me but i dunno how to fix

  11. 11 martin May 21st, 2008 at 7:10 am

    @betehes:

    i think i found a solution, changing the itemrenderer to:

    worked in my case

  12. 12 martin May 21st, 2008 at 7:16 am

    ^^change the image tag in the itemrenderer to this, and link display namespace to “flash.display.*”

    <mx:Image>
        <mx:source>
            <display:Bitmap bitmapData="{data.source}">
            </display:Bitmap>
        </mx:source>
    </mx:Image>
    

    sry for double post…seems wordpress has big issues with “greater than” and “smaller than” characters

  13. 13 martin May 21st, 2008 at 7:17 am

    data.source should be data.image.displayObject in that case

  14. 14 vivek Jul 23rd, 2008 at 5:21 am

    Hello,

    Is there any way to copy data from SWFLoader instance?

    Thanks

  15. 15 zyanlu Aug 10th, 2008 at 10:21 pm

    thanks martin.

    your solution is great!

Leave a Reply

This blog is terrible at eating HTML tags. If you plan on posting code/XML, please escape your "<" characters as "&lt;" and your ">" characters as "&gt;".