Jun 10 2009

New generative art series

After months of experimenting with the medium, I’m finally pleased with the results of my generative art engine. Next thing on the list is to create some high resolution pieces and then print and frame the best ones.

Here are some of my latest artworks:

If anyone is interested in buying high quality glicee prints (signed and numbered offcourse), let me know.


Jun 6 2009

Marching ants selection marquee in Flex

A while ago, when working on a Flex application, I was in need of a nice visual for when the user is selecting multiple items. We are all familiar with the marching ants selection rectangle in tools like Photoshop, so I decided to implement selection the same way as in Photoshop.
There are already some free resources out there, but most of them aren’t in actionscript 3, or incomplete.
So, I thought I’d share my version, maybe this could be usefull to someone.

Here’s my marching ants visual class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package be.vip.marchingantsdemo.view
{
    import flash.display.BitmapData;
    import flash.geom.Matrix;
    import flash.geom.Rectangle;
   
    import mx.core.UIComponent;

    public class MarchingAntsSelectionRectangle extends UIComponent
    {
        private var horizontalBitmap:BitmapData;
        private var verticalBitmap:BitmapData;
        private var _rect:Rectangle;
        private var _lineThickness:Number=1;
        private var bitmapScroll:Number=0;
       
        public function MarchingAntsSelectionRectangle()
        {
            super();
            width=0;
            height=0;
            includeInLayout=false;
            horizontalBitmap=new BitmapData(4,2,false,0XFFFFFF);
            verticalBitmap=new BitmapData(2,4,false,0XFFFFFF);
            initBitmaps();
        }
        public function get rect():Rectangle{
            return _rect;
        }
        public function set rect(value:Rectangle):void{
            _rect = value;
            if(initialized)
                update();
        }
        public function clear():void{
            graphics.clear();
        }
        public function get lineThickness():Number{
            return _lineThickness;
        }
        public function set lineThickness(value:Number):void{
            _lineThickness = value;
            if(initialized)
                update();
        }
        private function scrollBitmaps():void{
            bitmapScroll++;
            if(bitmapScroll>3)
                bitmapScroll=0;
        }
        private function initBitmaps():void{
            for(var _x:Number=0;_x<2;_x++){
                for(var _y:Number=0;_y<2;_y++){
                    horizontalBitmap.setPixel(_x,_y,0x000000);
                    verticalBitmap.setPixel(_x,_y,0x000000);
                }
            }
        }
        private function update():void{
            scrollBitmaps();
            graphics.clear();
           
            graphics.beginBitmapFill(horizontalBitmap,new Matrix(1, 0, 0, 1, bitmapScroll, 0),true,false);
            graphics.drawRect(_rect.x,_rect.y-lineThickness,_rect.width,lineThickness);
            graphics.drawRect(_rect.x,_rect.y+_rect.height,_rect.width,lineThickness);
           
            graphics.beginBitmapFill(verticalBitmap,new Matrix(1, 0, 0, 1, 0, bitmapScroll),true,false);
            graphics.drawRect(_rect.x-lineThickness,_rect.y-lineThickness,lineThickness,_rect.height+(lineThickness*2));
            graphics.drawRect(_rect.x+_rect.width,_rect.y-lineThickness,lineThickness,rect.height+(lineThickness*2));
        }
       

    }
}

It extends UIComponent, so it’s ment to be used inside a Flex application. If you want to use it in Flash, you can change it so it extends Sprite.

And here’s a small example of how to use it. I created a canvas, added some standard components, and added the marching ants selection marquee. I also added some actionscript code to highlight the selected components. For this simple demo, I just show a green glowfilter on top of the selected components.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas clipContent="false" addedToStage="creationComplete_handler()" xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="400" backgroundColor="#FFFFFF" backgroundAlpha="1.0" xmlns:view="be.vip.marchingantsdemo.view.*">
    <mx:Script>
        <![CDATA[
            import mx.core.UIComponent;
            private var selectionRect:Rectangle;
            private var clickPoint:Point;
           
            private function creationComplete_handler():void{
                stage.addEventListener(MouseEvent.MOUSE_DOWN, startSelectionDrawing_handler);
                stage.addEventListener(MouseEvent.MOUSE_UP, stopSelectionDrawing_handler);
            }
            private function startSelectionDrawing_handler(evt:MouseEvent):void{
                selectionRect=new Rectangle();
                selectionRect.x=mouseX;
                selectionRect.y=mouseY;
                selectionRect.width=1;
                selectionRect.height=1;
                addEventListener(Event.ENTER_FRAME,updateSelection_handler);
            }
            private function stopSelectionDrawing_handler(evt:MouseEvent):void{
                removeEventListener(Event.ENTER_FRAME,updateSelection_handler);
                marchingAntsSelectionRect.clear();
                selectItems();
                selectionRect=null;
            }
            private function updateSelection_handler(evt:Event):void{
                selectionRect.width=mouseX-selectionRect.x;
                selectionRect.height=mouseY-selectionRect.y;
                marchingAntsSelectionRect.rect=selectionRect;
            }
            private function selectItems():void{
                if(selectionRect!=null){
                    if(selectionRect.width<0){
                        selectionRect.x=selectionRect.x+selectionRect.width;
                        selectionRect.width=selectionRect.width*-1;
                    }
                    if(selectionRect.height<0){
                        selectionRect.y=selectionRect.y+selectionRect.height;
                        selectionRect.height=selectionRect.height*-1;  
                    }
                    for (var i:Number=0;i<numChildren;i++){
                        if(selectionRect.intersects(getChildAt(i).getRect(this))){
                            getChildAt(i).filters=[new GlowFilter(0x33FF33,1,3,3,4,1)];
                        }else{
                            getChildAt(i).filters=[];
                        }
                    }
                }
            }
        ]]>
    </mx:Script>
    <mx:Button x="120" y="91" label="Button"/>
    <mx:CheckBox x="120" y="121" label="Checkbox"/>
    <mx:ColorPicker x="120" y="151"/>
    <mx:ComboBox x="120" y="181"></mx:ComboBox>
    <mx:Label x="120" y="211" text="Label"/>
    <mx:NumericStepper x="120" y="237"/>
    <mx:TextInput x="120" y="267"/>
    <view:MarchingAntsSelectionRectangle lineThickness="1" x="0" y="0" id="marchingAntsSelectionRect"/>
</mx:Canvas>

And last but not least, here’s what this little demo looks like (just click and drag anywhere to make a selection):

As you see, its very easy to set it up, and it defently adds some value to your application when the user needs to select multiple items by clicking and dragging.

For those of you who are interested in this demo application, you can download it here (in Flex, just click File–>import–>flex project–>from archive file and then point to the zip)


May 20 2009

Multi Mania 2009

Yesterday I went to Multi Mania, a free multimedia event in Kortrijk, Belgium. This year the event was stretched out over 2 days, one with workshops aimed at professionals, and one day with speaker sessions.
The first day was already fully booked when I tried to register, so I decided to go listen to some of the speakers on the second day.
Here are the sessions I attended:

Hot tips to improve your textlife - by Sakri Rosenstrom
This session covered the new text rendering engine in Flash player 10. Very interesting stuff. I really need to play with these new text rendering capabilities!

Flash platform “next’ - by Serge Jespers and Enrique Duvos
This session gave insight into what our workflow could look like in the future. They showed us Flash Catalyst, which used to be Thermo. Adobe changed the name, but the concept stays the same. Designers can use this tool to create designs in Photoshop or Illustrator, and create a Flex mockup from this. They can then pass this on to a developer who can add the functionality and the server communication code.
For my work at Epyc I’m already using the skinning capabilities in Flex extensively, but in general graphics designers don’t like to work with a tool like Flex builder. So in the past I always converted the design into a Flex skin myself (which could later on be edited again by a graphics designer). Flash Catalyst could make our life a lot easier. We’ll see once it has been released. I’m looking forward to playing with this!

Away 3D and the future of 3D in Flash - by Rob Bateman
When I need 3D in Flash, I normally use PaperVision3D. It was the first Flash 3D engine I used, and I stuck with it. It looks like both engines have their pros and cons. But, now I’ve seen Away 3D’s features, I really want to play with it. So, if I find some free time… I’ll give it a go.

Flex 4 - by Christoph Rooms
Also a very interesting session. I am an avid user of Flex builder 3. I heard of Flex 4 before, but I didn’t really know what the new features would be. I must say: I’m impressed. Adobe is working hard trying to close the gap between designers and developers, and with Flex 4 (and tools like Flash Catalyst) I think we’ll be another step closer. A lot of developers just use the standard Flex skin these days. I hope once Flex 4 is out, we’ll start to see more and more fully skinned applications.

Silverlight 3 in all it’s glory - by Gill Cleeren
Most sessions I’ve seen about Silverlight all contained a good portion of Flash bashing. Most Flash developers didn’t even bother reacting, we knew better. This session, however, was a lot more honest. I must say, it looks like Silverlight improved a lot! But to me, it still cannot compete with Flash (although…being able to work with a tool like Visual Studio is a huge plus). I will keep following the evolution though… maybe one day it’ll be the other way around. Meantime, I’ll just stick to Flash.

For a free event I can really recommend Multi Mania. You get to see some of the same speakers of the big Multimedia events, and there’s always a nice atmosphere.
See you next year!


May 6 2009

Generative art news

There seems to be some interest in the generative art pieces I recently made. More specifically in the “Obama series”. www.animalnewyork.com wrote a small article about it, and it was also mentioned on a blog on www.politico.com. Because of that last site the visitor count on my blog exploded. But unfortunately my last blog posts were all a bit technical, so that’s why I’m quickly posting a small update on my generative art projects.

After the “Obama series”, I was asked by Cullen Miller, an American composer and electronic musician, to create some artwork for his upcoming album. He asked me if I could use the same algorithm I used for the Obama portraits. Unfortunately the output of that algorithm is heavily dependent on the input image. The first results were rather dissapointing. So I had to change the code a bit, also added a lot more particles, but eventually this was the result:

Cullen Miller album art

I like how this turned out. Can’t wait to see it on print!

Besides this, there is nothing new but I’m working on a wii-flash project (using the wii mote to create art). However, it is too early to reveal anything. I will probably post some info here in the coming month.


Apr 26 2009

Batch compile and update publish profile using JSFL

Some time ago, for my work at Epyc, I ran into a “little” problem: I had to use old Flash animations and load these into a Flex application. When you load an old Flash animation into Flash 9, it becomes an instance of the AVM1Movie class.
The problem with this is that AVM1Movie objects can use methods and properties inherited from the DisplayObject class, but no interoperability (such as calling methods or using parameters) between the AVM1Movie object and AVM2 objects is allowed. I needed to be able to control these animations trough actionscript, and that simply wasn’t possible.
Fortunately, there was no actionscript in the old animation files, so opening the original .fla, and changing the publish profile to Flash 9, solved this problem. But… then I discovered that there were 2500 fla’s that needed to be updated this way. Horror! No way I was going to open all these flash files manually, update the settings and save them.
Flash comes with a javascript API, which allows you to script commands. So you are able to write your own “plugins”. I’ve never used JSFL before, so I did some research first. I found these blogposts on the web, that both covered a part of my problem:

Throwing them together, and adding some of my own magic… I ended up with this script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
var tempDoc=undefined;
if(fl.documents.length==0){
    tempDoc=fl.createDocument();
}
xui = fl.getDocumentDOM().xmlPanel(fl.configURI + "Commands/AutoConvertToFlash9.xml");
if(tempDoc){
    fl.closeDocument(tempDoc);
}
var exportlog="";
if(xui.dismiss=="accept"){
    var searchSubDir=xui.searchSubDir;
    var folder=xui.path;
    if(folder.substr(0,8)!="file:///"){
        folder="file:///"+folder.split(":").join("|").split("\\").join("/");
    }
    if(folder.substr(folder.length-1,1)!="/"){
        folder=folder+"/";
    }
}
exportlist=new Array();

checkFolder(folder,exportlist,searchSubDir);

var totaltime=0;
if(exportlist.length==0){
    alert("No file need to publish.");
}else{
    if(confirm(exportlist.length+" files will be updated and published")){
        for(var i=0;i<exportlist.length;i++){
            setPublishProfileSettings(exportlist[i]);
            //FLfile.write("file:///c:/exportlog.txt", exportlog);//uncomment if you want to log all files
        }
    }
}

function checkFolder(folder,list,checkSub,pre){
    if(pre==undefined){
        pre="";
    }
    var flas=FLfile.listFolder(folder+"*.fla","files");
    for(var i=0;i<flas.length;i++){
        list.push(folder+flas[i]);
    }
    if(checkSub=="true"){
        var flds=FLfile.listFolder(folder,"directories");
        for(var i=0;i<flds.length;i++){
            checkFolder(folder+flds[i]+"/",list,checkSub,pre+" ");
        }
    }
}

function setPublishProfileSettings(fileURI)
{
       if (fl.fileExists(fileURI))
        {
            var xml, from, to, delta;

            var doc=fl.openDocument(fileURI);

            var fileName = fileURI.split("/").pop();
            var folderPath = fileURI.split(fileName)[0];
            fileName = fileName.split(".")[0];

            var pPath = folderPath + "/_Profile_.xml";
            fl.getDocumentDOM().exportPublishProfile(pPath);
            xml = FLfile.read(pPath);

            var swfpath=fileName+".swf";
            from = xml.indexOf("<flashFileName>");
            to = xml.indexOf("</flashFileName>");
            delta = xml.substring(from, to);
            xml = xml.split(delta).join("<flashFileName>"+swfpath);

            from = xml.indexOf("<Version>");
            to = xml.indexOf("</Version>");
            delta = xml.substring(from, to);
            xml = xml.split(delta).join("<Version>9");

            from = xml.indexOf("<ActionScriptVersion>");
            to = xml.indexOf("</ActionScriptVersion>");
            delta = xml.substring(from, to);
            xml = xml.split(delta).join("<ActionScriptVersion>3");


            from = xml.indexOf("<AS3PackagePaths>");
            to = xml.indexOf("</AS3PackagePaths>");

            delta = xml.substring(from, to);
            var classPath = "./";
            if (fileName.indexOf("/") > -1)
            {
                classPath = "";
                var splitPath = fileName.split("/");
                splitPath.length--;
                var i = splitPath.length;
                while (i--)
                {
                    classPath += "../";
                }
            }

            xml = xml.split(delta).join("<AS3PackagePaths>" + classPath + "classes");

            FLfile.write(pPath, xml);
            fl.getDocumentDOM().importPublishProfile(pPath);

            fl.saveDocument( doc);
            fl.getDocumentDOM().publish();

            FLfile.remove(pPath);
            fl.closeDocument(doc);
            exportlog+="updated and exported " + fileURI+"\r\n";
        }
}

One small problem though. Flash warns you when you try to save an old .fla as a newer version. So, when I ran the script the first time, Flash gave a warning for each of the .fla files. This ment I had to press “ok” 2500 times! Luckily, this is just a setting. This can be turned off under “preferences -> Alerts”.

So, how do you use this?:

  • Download the files here
  • Extract the script, and place the script and the GUI under “Documents and Settings/[Your login id]/Local Settings/Application Data/Macromedia/[Your flash version]/[language]/Configuration/Commands/”
  • Run flash, you will see a new command named “AutoConvertToFlash9″ in the command menu.
  • Run the script, everything else should be obvious

I only tested this in CS3, but I think it will work fine under CS4 too. If you are a CS4 user, and this doesn’t work, please let me know and I’ll look into it.


Apr 16 2009

Flash AS3 code obfuscation (do it yourself)

We all know Flash can easiy be decompiled, and we all don’t want people stealing our codes. There are a couple of good commercial products out there that let you obfuscate your actionscript code. None of them are bullet proof, but they surely don’t make it easy for the occasional hacker to get your code.
So, lately I was thinking of ways to make it even harder. And I came up with this:

With actionscript 3 it is possible to load binary files into a ByteArray. It is also possible to load an SWF using a ByteArray as source (using the loadBytes() function of the Loader class). So, my idea was to encrypt an SWF file, load that SWF into a byteArray, decrypt it, and then show it. The decrypted SWF only exists in the memory, which makes it harder to decompile using the many Flash decompilers out there. So, I wrote a little AIR tool that lets you encrypt SWF files using a simple XOR algorithm (it can also be used to decrypt, because if you XOR an already XOR-red file with the same key, it will give you the original back). I then wrote a class that loads in an encrypted SWF file and adds it to the displaylist.

Why on earth did I use XOR for encryption when it’s so “easy” to crack? Because one can still decompile the loader movie, and see how the swf is decrypted. So putting your effort in making a better encryption algorithm is a waste of time. Still, this will prevent 99% of the people who know how to download your swf from decompiling it. So I decided to just use XOR. It leaves the file size intact, which is a big advantage over other encryption methods. It’s also fast, and simple.

This is not bullet-proof. It’s just another barrier. I recommend obfuscating the loader movie with an obfuscation tool like SWF Encrypt. Or even better, also obfuscate the main movie before encrypting it. Anyway, I’m throwing this into the public domain, so we can all figure out our own ways to obfuscate our code. If everyone uses the same techniques, we only make it easier for those who are chasing our codes. So use this as a starting point… and use your imagination.

Here’s the code for the loader (stub) movie:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//copyright 2009 Ward De Langhe
package
{
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    import flash.utils.ByteArray;

    public class EncryptedSWFLoader extends Sprite
    {
        private var binaryLoader:URLLoader;
           
        private static const ENCRYPTED_SWF_URL:String="./encryptedfile.swf";//put the url of the encrypted swf here
        private static const KEY:String="testkey";//put your encryption key here
       
        public function EncryptedSWFLoader()
        {
            super();
            binaryLoader = new URLLoader();
            binaryLoader.addEventListener(Event.COMPLETE, onLoadInit);
       
            binaryLoader.dataFormat = URLLoaderDataFormat.BINARY;
            binaryLoader.load(new URLRequest(ENCRYPTED_SWF_URL));
        }
        private function onLoadInit(e:Event):void
        {
            binaryLoader.removeEventListener(Event.COMPLETE, onLoadInit);

            var animationLoader:Loader = new Loader();

            var binaryData:ByteArray = new ByteArray();
            binaryData = binaryLoader.data;
               
            if(binaryData.length != 0)
            {
                 XOR(binaryData,KEY);
                animationLoader.loadBytes(binaryData);
                addChild(animationLoader);
            }
        }
        private static function XOR(binaryData:ByteArray, key:String):void{
            var keyIndex:Number=0;
            for(var i:Number=0;i<binaryData.length;i++){
                binaryData[i]=binaryData[i]^key.charCodeAt(keyIndex);
                keyIndex++;
                if(keyIndex>=key.length)
                    keyIndex=0;
            }
        }

       
    }
}

To create the encrypted SWF files you can use this AIR tool:
XORTool.air
I also uploaded a zip file with the source of the loader (or stub):
encryptedSWFLoader.zip
Here’s how you use these files:

  • Use the AIR tool to encrypt your Flash animation.
  • Open the .FLA in the zip file above and change the document width and height to size of your original movie.
  • Open EncryptedSWFLoader.as and change the value of ENCRYPTED_SWF_URL (at the top of the file) so it points to your encrypted SWF
  • Also change the KEY variable to the key you used to encrypt your file
  • Compile and you should see your original Flash animation appear