Browsing the archives for the classes category.

Actionscript 3 - PixelMorphing Class (now with source code)

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

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 200×200px (as in the linked previous post) and offset them of 200 on the x, the resulting bitmapdata for the pixelMorphing will be 400×200px. If you offset of 1000px on x axis and 1000px on y axis the resulting bitmapdata will be 1200×1200px. So pay attention with CPU load and memory consumption.

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

2 Comments

Actionscript 3 - Fun with isometrics (part2 (with source))

BitmapData, Math, actionscript 3, classes, equalizer, fun

Hi there,

back again with some funny isoStuff.
Here’s an optimized and enhanced version of the previous post, and with source code explained.
It now has dynamic colors and you can choose colors and size (for hi and low values).


See it moving

Ok now some explanation:
The main trick behind this (for who didn’t noticed) is that the code simply redraw at every frame just the first line of blocks. Then simply draw() that first line into a BitmapData that scrolls of a block size… and the trick lives!

Ok, speaking about optimization… two main things:
1. Draw it without a line (just fills) and it goes 2x faster
2. Even that first line (60 pieces only) was not actually so fast…

About this second point the code involved with sine-wave and dynamic colors calculation contains some math equation, but nothing can really send your CPU @100%. The main CPU draining comes from the visual/rendering part.
One solution I implemented in this experiment (and it’s a trick can be used very often) is simply draw into a bitmap even that first line without adding to childList the vector part. With this little trick fps went from 15 to 31 =).

The second thing is simply that you dont really need to redraw every block @ every frame to achive a cool effect. You could just change its y without changing size for a poorer effect but surely faster. However remember that changing y can lead to higher fps but will not be enough if you still move a lot of vector shapes on screen. Draw everything to a bitmap is rule #1 for speed issues.
You could even use slice-9 grids to change the height of a block or use an animation build with 100 frames and simple gotoAndPlay(value) so you don’t have to draw everything programmatically.

Of course you can use this base for everything you need. Display height maps (maybe I’ll be posting a example of this), equalizers etc.

Now comes the code. First you will need the two classes involved.

The classes are not packaged and very simple. Simply extract them in the main dir or package them in some “common classes/com/oaxoa/blabla” folder
This was written very fast so no packaging, don’t expect setters/getters for every parameter or perfectly protected vars etc.

Ok you got the classes, now the main code. Just the first 30 lines are really needed. The rest is just to add and layout the sliders and colorpickers components.

import IsoField;
import com.oaxoa.components.FrameRater;
import fl.controls.ColorPicker;
import fl.controls.Slider;
 
var minsize:Number=10;
var maxsize:Number=10;
var spacing:Number=10;
var angle:Number=45;
var angleRadians:Number=angle/180*Math.PI;
var isofield:IsoField=new IsoField(1, 60, minsize, maxsize, spacing, angle, 0x00ffff, 0xff9900);
 
isofield.x=50;
isofield.y=50;
 
var bd:BitmapData=new BitmapData(800, 600, false, 0xffffff);
var bmp:Bitmap=new Bitmap(bd);
 
addChild(bmp);
addChild(isofield);
 
addEventListener(Event.ENTER_FRAME, onframe);
 
function onframe(event:Event):void {
	isofield.cycle();
	var matrix:Matrix=new Matrix();
	matrix.translate(50, 50);
	bd.draw(isofield, matrix);
	bd.scroll(spacing*Math.sin(angleRadians), -spacing*Math.cos(angleRadians));
}
 
// Main code end here. Stuff below is just to add sliders, labels and color pickers.
 
// add the frameRater
var fr:FrameRater=new FrameRater();
addChild(fr);
 
// add colorpickers
var cp1:ColorPicker=new ColorPicker();
cp1.x=20;
cp1.y=470;
cp1.selectedColor=0x00ffff;
addChild(cp1);
cp1.addEventListener(Event.CHANGE, oncp1);
 
var cp2:ColorPicker=new ColorPicker();
cp2.x=60;
cp2.y=470;
cp2.selectedColor=0xff9900;
addChild(cp2);
cp2.addEventListener(Event.CHANGE, oncp2);
 
function oncp1(event:Event):void {
	isofield.mincolor=cp1.selectedColor;
}
 
function oncp2(event:Event):void {
	isofield.maxcolor=cp2.selectedColor;
}
 
// add sliders
 
var slider1:Slider=new Slider();
slider1.minimum=4;
slider1.maximum=10;
slider1.value=10;
slider1.snapInterval=1;
slider1.liveDragging=true;
slider1.x=20;
slider1.y=510;
slider1.addEventListener(Event.CHANGE, onslider1);
addChild(slider1);
 
var slider2:Slider=new Slider();
slider2.minimum=4;
slider2.value=10;
slider2.maximum=10;
slider2.snapInterval=1;
slider2.liveDragging=true;
slider2.x=20;
slider2.y=540;
slider2.addEventListener(Event.CHANGE, onslider2);
addChild(slider2);
 
var slider3:Slider=new Slider();
slider3.minimum=-10;
slider3.value=6;
slider3.maximum=10;
slider3.snapInterval=1;
slider3.liveDragging=true;
slider3.x=20;
slider3.y=570;
slider3.addEventListener(Event.CHANGE, onslider3);
addChild(slider3);
 
var labelStr1:String="<b>Minimum size:</b> ";
var labelStr2:String="<b>Maximum size:</b> ";
var labelStr3:String="<b>Wave speed:</b> ";
 
function onslider1(event:Event):void {
	sliderLabel1.htmlText=labelStr1+String(slider1.value);
	isofield.minsize=slider1.value;
}
 
function onslider2(event:Event):void {
	sliderLabel2.htmlText=labelStr2+String(slider2.value);
	isofield.maxsize=slider2.value;
}
 
function onslider3(event:Event):void {
	sliderLabel3.htmlText=labelStr3+String(slider3.value);
	isofield.xfSpeed=slider3.value/1000;
}
 
var tf:TextFormat=new TextFormat();
tf.font="_sans";
 
var sliderLabel1:TextField=new TextField();
sliderLabel1.x=slider1.x+slider1.width+20;
sliderLabel1.y=slider1.y;
sliderLabel1.width=200;
sliderLabel1.selectable=false;
sliderLabel1.defaultTextFormat=tf;
sliderLabel1.htmlText=labelStr1+String(slider1.value);
addChild(sliderLabel1);
 
var sliderLabel2:TextField=new TextField();
sliderLabel2.x=slider2.x+slider2.width+20;
sliderLabel2.y=slider2.y;
sliderLabel2.width=200;
sliderLabel2.selectable=false;
sliderLabel2.defaultTextFormat=tf;
sliderLabel2.htmlText=labelStr2+String(slider2.value);
addChild(sliderLabel2);
 
var sliderLabel3:TextField=new TextField();
sliderLabel3.x=slider3.x+slider3.width+20;
sliderLabel3.y=slider3.y;
sliderLabel3.width=200;
sliderLabel3.selectable=false;
sliderLabel3.defaultTextFormat=tf;
sliderLabel3.htmlText=labelStr3+String(slider3.value);
addChild(sliderLabel3);

As usual I do like comments, so if you enjoy this (or not and want your five minutes back) -gogogo- leave one (and subscribe to my feed!) :D

4 Comments

Asciify - Actionscript 3 (as3) Ascii Art class

BitmapData, actionscript 3, ascii art, classes

There are trends on the web (as in real world) that last days or weeks and there are things that became a classic form of expression of the geek culture and are still interesting to explore after 20+ years.

Ascii Art is one of these things. If you don’t know what ascii art is you’re probably reading the wrong blog, however for the one or two that doesn’t know about it, here you can learn more about it: Ascii art on wikipedia.

I always had in mind the idea to create an actionscript class to render ascii art from pictures and now with as3 this is going to be possible at decent speed.

My class is called Asciify and it can actually “ascii-fy” every DisplayObject instance on the display list.

Usage is very simple and it’s actually REALLY fast.
Didn’t think AVM2 could asciify a video in real time but I was wrong. You cannot go further certain resolutions but if you stay on small videos with decent detail 30fps are guaranteed.

This is the constructor method:

public function Asciify(targetClip:DisplayObject, tformat:TextFormat, pixelSize:Number=8, negative:Boolean=false) {

and this is a sample usage:

var asciifyInstance:Asciify=new Asciify(picture, textFormat, 16);
addChild(asciifyInstance);

Demos & download

See a working demo here:
Asciify class test demo 1
Pictures demo

Another demo applied to a video (see original video here)… this demo uses a glow effect too that make you loose a couple o fps but I couldn’t resist:

Asciify class test demo 2
Video demo

You can offcourse apply it to an animated movieclip or anything else.
In this demos I use ProggyCleanTT font, but you can use any monospaced font that must be imported into the library and have a linkage (in this case I gave it “Font1″ linkage name).
Then just play a little with size, leading and kerning of the textformat to achive the desired effect.

Here is the class:

Asciify class download

Just extract it to [your custom classes folder]/com/oaxoa/fx/

Here is the code for the video demo:

import fl.controls.Button;
import flash.events.Event;
import flash.text.TextFormat;
import flash.filters.GlowFilter;
import fl.controls.CheckBox;
import com.oaxoa.fx.Asciify;
import com.oaxoa.components.FrameRater;
 
var glow:GlowFilter=new GlowFilter(0xffff00);
 
/*******************************************/
 
// setup the TextFormat object to use
var font:Font=new Font1();
var textFormat:TextFormat=new TextFormat();
textFormat.font=font.fontName;
textFormat.size=16;
textFormat.leading=-9;
textFormat.color=0xffff00;
 
// create an istance of the class and add a nice glow filter
var asciifyInstance:Asciify=new Asciify(video, textFormat, 6);
asciifyInstance.y=30;
asciifyInstance.filters=[glow];
addChild(asciifyInstance);
 
// update asciifyInstance at every frame
addEventListener(Event.ENTER_FRAME, onframe);
 
function onframe(event:Event):void {
	asciifyInstance.render();
}
 
/*******************************************/
 
// just add some interface for the demo
// you don't really need stuff below this line
 
var interfaceFormat:TextFormat=new TextFormat();
interfaceFormat.color=0xffffff;
interfaceFormat.size=12;
 
var cb:CheckBox=new CheckBox();
cb.label="Glow active";
cb.y=4;
cb.x=260;
cb.setStyle("textFormat", interfaceFormat);
cb.selected=true;
addChild(cb);
 
cb.addEventListener(Event.CHANGE, oncb);
 
function oncb(event:Event):void {
	cb.selected ? asciifyInstance.filters=[glow] : asciifyInstance.filters=[];
}
 
var button:Button=new Button();
button.label="Copy frame to clipboard";
button.y=4;
button.x=70;
button.width=170;
button.setStyle("textFormat", interfaceFormat);
addChild(button);
 
button.addEventListener(MouseEvent.CLICK, onclick);
 
function onclick(event:MouseEvent):void {
	asciifyInstance.copyContentsToClipboard();
}
 
var fr:FrameRater=new FrameRater(0xffffff);
fr.x=10;
fr.y=4;
addChild(fr);
28 Comments

Fountain equalizer now with source code

Particles, actionscript 3, classes, equalizer

I just edited the Fountain equalizer post adding the source code.
You’ll just need to download the two particles classes and copy the main code.

I received really a lot of requests about the code in the comments and by mail, and I am very pleased about this… means you liked it.

Expect more equalizing fun.

1 Comment

Actionscript 3 - PixelMorphing class first test (morphing with particles)

BitmapData, Particles, actionscript 3, classes, morphing

Hi there,
I am back after some pause with this interesting effect. This class takes every pixel from two pictures, sort them by averaged luminosity e reconstruct the second picture animating pixels from the first one.

The effect is a very nice pixel morphing (particles morphing) and the final result resambles some color ramp recolor tecnique.

pixelmorphing_test.jpg
Start demo

This is the second algorythm I wrote. The first one was build to do the calculation about moving pixels and then draw the full picture parsing the full array of pixels. The bigger problem in the first one was speed of execution.

The setPixel method of the BitmapData class is far too slow for this kind of effect and even slower was the parsing every frame of the full array containing all the pixel of the first image.

So I come with completely new algorythm that uses three bitmaps/bitmapdatas where the first only displays original image and set to trasparent only pixels that have moved away.
The scond one redraws every frame, but only displays moving pixels which are stored in a much shorter array and the last one shows only pixels which reached the final position.

With this second approach only pixels effectively changing are redrawn and a lot of speed can be gained.

This first post is only for showcase, during next days I will write a technical post about class structure, speed optimisations etc. off course with source code.

Don’t forget to leave a comment if you like it ;-)

16 Comments

Actionscript 3 FrameRater Class

FrameRater,