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.
<?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.





Good sample of bitmap operation, thank your for sharing experience!
Very nice! I wait for the next example.
Good one! Thanks.
~Tushar
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.
techpop,
I think I have an example of grabbing video stills from an VideoDisplay control whenever it encounters a
cuePointevent. Regardless, it should be fairly easy if you use the Timer class or maybe listen for the VideoDisplay control’splayheadUpdateevent.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 forBitmapData.compare()).Peter
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?
judah,
No reasons, I think this was just the first approach that came to mind.
Peter
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
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.
@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
@betehes:
i think i found a solution, changing the itemrenderer to:
worked in my case
^^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
data.source should be data.image.displayObject in that case
Hello,
Is there any way to copy data from SWFLoader instance?
Thanks
thanks martin.
your solution is great!