Actionscript 3 – PixelMorphing Class (now with source code)

actionscript 3, advanced image editing, algorithms, BitmapData, classes, fun, morphing, Particles

Updated on 04/27/2009: Class with some improvements to skip transparent pixels. The two images should however share the same amount (or similar) of visible pixels.
Lot of space for improvements here, if someone want to contribute very appreciated.

Ok, lot of time passed since I posted my PixelMorphing class experiment.
Seemed to me that post passed quite unobserved but then I received a lot of feedback and e-mail asking to share the source code.

Well, the first time I wanted to speed up posting and do further experimentation/optimization so I din’t prepare the source but since the main believe of this blog is that if someone ask for code I release it, here we are. Optimization still not done… I am a lazy one, so if someone want to help improve it is really welcome.

Now the steps to play with it:

  1. Download the PixelMorphing class
  2. Use it with this code:
import com.oaxoa.fx.PixelMorphing;
var pm:PixelMorphing=new PixelMorphing(pic1, pic2, 200);
addChild(pm);

pm.start();
//pm.reset();

or certainly you can place some buttons or some combo and wait for some event for it to start or reset. The main code of the previous post is this:

import com.oaxoa.fx.PixelMorphing;
import fl.controls.Button;
import fl.controls.ComboBox;

var pm:PixelMorphing=new PixelMorphing(pic1, pic2, 200);
addChild(pm);

var button1:Button=new Button();
button1.label="Start";
button1.y=203;
button1.x=3;
addChild(button1);
button1.addEventListener(MouseEvent.CLICK, onstart);

var button2:Button=new Button();
button2.label="Reset";
button2.y=203;
button2.x=3;
addChild(button2);
button2.addEventListener(MouseEvent.CLICK, onreset);



button1.width=button2.width=60;
button1.height=button2.height=25;
button2.visible=false;

function onstart(event:MouseEvent):void {
	pm.start();
	button1.visible=false;
	button2.visible=true;
}
function onreset(event:MouseEvent):void {
	pm.reset();
	button2.visible=false;
	button1.visible=true;
}

var ls:ComboBox=new ComboBox();

ls.addItem({label: "Sample 1", value: 1});
ls.addItem({label: "Sample 2", value: 2});
ls.addItem({label: "Sample 3", value: 3});
ls.addItem({label: "Sample 4", value: 4});
ls.addEventListener(Event.CHANGE, onpreset);

ls.x=66;
ls.y=203;
ls.height=25;

addChild(ls);

function onpreset(event:Event):void {
	button2.visible=false;
	button1.visible=true;
	pic1.gotoAndStop(ls.selectedItem.value);
	pic2.gotoAndStop(ls.selectedItem.value);
	pm.reset();
}

You can find more parameters in the constructor method of the class, but only the first two are needed.

No setters & getters for the main variables but they are public so change them then invoke reset/start method if you wanna play with their values.

Parameters names are quite self-explainatory about what they do but remember one thing:
3rd and 4th parameters are offsetX and offsetY which influence if the starting and the resulting images will bel overlapped in the same position or offsetted. However I needed jsut one bitmapData to be able to move pixels across the two images. So if you have the 2 pictures that are 200x200px (as in the linked previous post) and offset them of 200 on the x, the resulting bitmapdata for the pixelMorphing will be 400x200px. If you offset of 1000px on x axis and 1000px on y axis the resulting bitmapdata will be 1200x1200px. So pay attention with CPU load and memory consumption.

Leave some comment if something not clear or just want to say hello ;)

19 Comments

19 Comments

  1. wonderwhy-er  •  Sep 27, 2008 @10:49 am

    Wow just checked the demo. New to your blog so haven’t seen it. Very cool idea. I especially like 4 example where colors in painter style is used :)

  2. batchass  •  Sep 27, 2008 @5:34 pm

    great! great! great!
    what is your development environment?
    Thanks

  3. Pascal  •  Oct 10, 2008 @5:20 pm

    This is great, thank you very much for sharing the source files.
    One thing I don’t understand though: When using pngs with transparent parts it fills the final pic with opaque pixels in the end. I wish it didn’t do that and don’t understand why it does. Is there any way to avoid this problem?

  4. Pierluigi Pesenti  •  Oct 10, 2008 @5:31 pm

    I didn’t notice this cause I didn’t any test with transparent pngs.
    I will investigate and post solution. I think I will have sometime during the weekend.

    Thanks for debuggin ;)

  5. Pascal  •  Oct 16, 2008 @4:14 pm

    I found the solution. In the function “analyzePicture” one needs to add bd.fillRect(bd.rect, 0x00000000);
    The result sucks though, because there will be invisible Pixels morphing, leaving the viewer thinking that nothing’s happening. I guess it’s okay, when there aren’t too many transparent Pixels.

  6. alfred  •  Oct 28, 2008 @1:04 am

    Very nice tutorials, searching a whole day finding only as that didn’t work at all, this is a positive thing indeed.

    thanx !

  7. mathmass  •  Feb 14, 2009 @1:52 am

    do i have to use a movieclip on the stage of an swf with this.. in using flashdevelop

  8. ricardo  •  Mar 19, 2009 @6:59 pm

    Man, we have to fix the transparency problem … Pascal cames with a solution, but when an image has to many transparency the result is bad

  9. Pierluigi Pesenti  •  Mar 20, 2009 @9:00 am

    In this class no pixels are created, all the pixels are recycled from the first picture to the second (this makes the morphing thing). If you want to use it with transparent pngs you have to do it with two pictures with the same transparent pixel count and skip the transparent pixels.

  10. erik  •  Apr 13, 2009 @5:09 pm

    this is very very cool, and seems to be implemented with quite little fuss. I finally found a reason to use it! I wish I new the inner workings a bit more so I could optimize for my specific use, but many thanks for posting the code, I will be sure to credit you and let you know how it gets used and if any modifications are made. A thought on the transparent pixels, could you not make sure they were the last pixels to be moved, then color/alpha transform them where necessary? maybe this is not even possible, just thinking out loud.

    have you seen the awesome experiments of the 3D particles on Flash & Math site? would be cool to combine these somehow.

  11. Pierluigi Pesenti  •  Apr 13, 2009 @6:00 pm

    What’s the url of flash & math? I’ll google it.

    However, I am happy you will use it and cannot wait to see the result. About the transparent pixels I had so many requests I spent some time on it and it actually works. In the next few days I’ll pack it a little with some tests and the publish the update.

    Byez

  12. erik  •  Apr 13, 2009 @7:26 pm

    here is the link, sure you found it but for others maybe too:

    http://www.flashandmath.com/advanced/fourparticles/index.html

    There is also an earlier version of his experiments that uses an image, very beautiful stuff.

    Look forward to the new pack. will check back soon.

  13. erik  •  Apr 27, 2009 @2:06 am

    any luck packaging up the transparent pixel version?

  14. Pierluigi Pesenti  •  Apr 27, 2009 @9:19 am

    You are right, I should post for priority. I’ll do this this afternoon (GMT+1)

  15. Pierluigi Pesenti  •  Apr 27, 2009 @9:00 pm

    Ok republished. I didn’t have time to check anything, but I run it and saw that it simply works, so perhaps last time a did finish the job :-D

  16. Badger Manufacture  •  Jul 25, 2009 @11:37 pm

    Really great work! I have managed to work with your code and use a couple of functions. I will forward a demo if you like.

    Regards :)

    Barnaby John Byrne aka Badger

  17. Badger Manufacture  •  Jul 26, 2009 @7:39 pm

    Thanks again for the excellent tutorials. As I am new to AS3.0 I really appreciate the help.

    I am having a little difficulty in passing bitmapdata to Pixel Morphing. How do you convert a bitmap/bitmapdata to a DisplayObject? I can do it the other way around lol!

    :) Badger

  18. Marc87  •  Dec 9, 2009 @4:20 pm

    hey, I’m trying to fit the code into a small project but I’m getting this error:

    ArgumentError: Error #2015: Invalid BitmapData.
    at flash.display::BitmapData()
    at PixelMorphing/analyzePicture()
    at PixelMorphing/reset()
    at PixelMorphing()
    at BannerAd_fla::MainTimeline/frame1()

    As far as I know the size of the file is right, but its just not working, there’s probably an easy answer, but I’m not seeing it, anyone know what the cause is?

  19. Andreas  •  Dec 21, 2009 @10:41 am

    Thanks for this Pierluigi, it looks great :D

    A very late reply but might help someone else too:
    @Badger_Manifacture : As long as a bitmap gets on stage by addChild(some bitmap) it’s on the DisplayObject container and it should work.

Leave a Reply

Allowed tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>