ActionScript 3 Bitmap Tracer (Vectorizer): as3potrace

Ever wanted to convert a bitmap to vector shapes, at runtime, in Flash? Look no further. Let me introduce you to as3potrace, an ActionScript 3 library to trace bitmaps.

As the name suggests, this is a port of the well known C library potrace by Peter Selinger. To be more exact, it is a AS3 port of Vectorization, a C# port of potrace 1.8 by Wolfgang Nagl.

Like potrace, as3potrace is released under GPL. The SWC and source code are available on GitHub:

https://github.com/PowerflasherBR/as3potrace

Demo

[SWF]http://wahlers.com.br/claus/blog/wp-content/uploads/POTrace.swf, 475, 475[/SWF]

Demo source code: https://gist.github.com/940219 (Warning: ugly)

Usage example

A minimal example of how to trace a bitmap with as3potrace, and draw the result into a Shape:

Note that you can write your own backends to ease handling/processing of generated shapes. The one backend that i already wrote, GraphicsDataBackend, produces GraphicsData structures that you can immediately draw using Graphics.drawGraphicsData().

Alternatives

And as always, after i finished porting this little beauty, i found out that this has been done before by the amazing folks at LibSpark. Check out nitoyon’s PotrAs (also GPL’ed).

Flash IDE Inspired Flex 4 Timeline Component

Here’s a little demo of a Flex 4 component i wrote that displays a Flash IDE-like timeline for any SWF you load into it. The timeline data is reconstructed by as3swf (i discuss how that works in a previous blog post, SWF Timeline Reconstruction with as3swf). The timeline is not interactive in this demo, and only the root timeline is shown.

Continue reading

My Silly Gist Collection

I’ve been quite busy lately on both client and personal projects (can’t talk about the former, other than it being a big ass Flex 4 enterprise application i’ve been working on for the fine folks at Powerflasher; and it’s too early to talk about the latter.. stay tuned).

In the last few weeks i silently released random little experiments on Gist – mostly fallout from personal projects of mine. Nothing super impressive, all pretty rough, but i thought some of you might be interested.

Continue reading

Realtime MP3 Decoding in Actionscript 3

So did you ever try to play Shoutcast streams in Flash? Did you run into memory leaks? Did the playback sound pitched or otherwise screwed? Fear no more. Let me introduce you to as3icy.

as3icy is a drop-in replacement for the Flash Player’s Sound object that can reliably play Shoutcast, Icecast and Limewire MP3 streams. And it extracts metadata info from the stream in real time. It also reliably plays VBR MP3.

Continue reading

Posted in AS3

SWFtrospection

Open Flash CS4, create new AS3 FLA, add as3swf.swc and paste this on frame 1:

import com.codeazur.as3swf.SWF;
var swf:SWF = new SWF(root.loaderInfo.bytes);
trace(swf);

Trace output:

[SWF]
  Header:
    Version: 10
    FileLength: 149405
    FileLengthCompressed: 149405
    FrameSize: (550,400)
    FrameRate: 24
    FrameCount: 1
  Tags:
    [69:FileAttributes] AS3: true, HasMetadata: false, 
      UseDirectBlit: false, UseGPU: false, UseNetwork: false
    [09:SetBackgroundColor] Color: #FFFFFF
    [86:DefineSceneAndFrameLabelData] 
      Scenes:
        [0] Frame: 0, Name: Scene 1
    [82:DoABC] Lazy: true, Length: 149219
    [76:SymbolClass] 
      Symbols:
        [0] TagID: 0, Name: Untitled_fla.MainTimeline
    [01:ShowFrame] 
    [00:End]

Excercise: Draw something on stage, and run the code again.

Want more? Drop by my session Hacking SWF at FITC Amsterdam (Feb 22th, 16:00).

[Edit] Jim Cheng deserves credits. He was the one who whispered “root.loaderInfo.bytes” into my virtual ear on IM.

Undocumented SWF Tags written by MXMLC

While testing my AS3 SWF library as3swf yesterday, i found that MXMLC (the compiler that comes with the Flex SDKs)  writes undocumented SWF tags to the SWFs it produces.

I was able to identify two so far:

ProductInfo (Tag ID 41)

The ProductInfo tag contains infos about the tool used to generate the SWF, as well as the date and time the SWF was compiled. It also contains info about the “Edition” of the software used (see below), and although this seems to be always set to “None” in Flex Builder 3 and Flash Builder 4, it potentially could become a privacy issue, especially being an undocumented feature (you better know about this tag just in case you accidentally publish commercial work with your non commercial Flash Builder license).

  • ProductID (UI32)
    0: Unknown
    1: Macromedia Flex for J2EE
    2: Macromedia Flex for .NET
    3: Adobe Flex
  • Edition (UI32)
    0: Developer Edition
    1: Full Commercial Edition
    2: Non Commercial Edition
    3: Educational Edition
    4: Not For Resale (NFR) Edition
    5: Trial Edition
    6: None
  • MajorVersion (UI8)
  • MinorVersion (UI8)
  • BuildLow (UI32)
  • BuildHigh (UI32)
  • CompilationDate (UI64)
    Milliseconds since 1.1.1970

Examples:

Flex 4.0 – [41:ProductInfo] ProductID: 3, Edition: 6, Version: 4.0.0.7791, CompileDate: Fri Aug 21 05:18:21 GMT-0300 2009

Flex 3.2 – [41:ProductInfo] ProductID: 3, Edition: 6, Version: 3.2.0.3958, CompileDate: Fri Aug 21 05:23:22 GMT-0300 2009

DebugID (Tag ID 63)

This tag is written to SWFs that are enabled for debugging. It contains a 16 byte UUID.

  • UUID (UI8[16])

Example:

[63:DebugID] UUID: b8f36d6a-c735-a340-daa7-44730af92505

Reference

Flex SDK:

Community:

Custom Installer For Adobe AIR Applications

I need a custom installer for an AIR application i’m currently developing. That’s because my AIR app needs additional functionality that the AIR runtime doesn’t provide (specifically: detecting USB storage devices, act as a TCP socket server, talk to Last.fm scrobbler plugins). For that purpose i wrote a local RPC socket server gateway in C (one for Mac OS X and one for Windows) which always runs once the user logs in to her OS. The AIR application can then call methods on that local gateway, or receive events.

The problem is that the user needs to install the RPC server before she installs the actual AIR application. The install process should be seamless (one installer installs RPC server, AIR runtime if needed, and the application itself in one go) and the installer should be as small as possible. Currently there is no info available from Adobe on how to write custom installers that automatically download/install the AIR runtime if needed (is there?).

Artemis is another project aiming at extending AIR using a local socket server, but it seems that the project has been shut down because of the reasons stated above.

So i have been pulling out my hair lately on how to solve that problem.

I think i found a feasible solution. I am not sure because i haven’t tested all this, but i wanted to throw it online for discussion. The drawback is that the user needs to install your application with a OS native custom installer.

First you write standard installers for both Mac OS X and Windows, that install the local socket server either as a service/daemon or as an agent so that the server always starts at system launch or user login. Nothing special here yet.

The trick would be to write a simple SWHX application that basically implements the code included with the AIR Installer badge. That helper application can then be included with the installer, which executes it after the local socket server has been installed.

As i said i haven’t tested this yet (will do soonish), but this should work, no?

The question remains why i don’t just use SWHX for the main app and screw AIR alltogether.

FZip Alpha Release: Create And Modify ZIP Archives

FZip has been around for some time now, and people seem to like it. However one feature has been asked for repeatedly: In addition to reading ZIP archive, people want to be able to create new (and modify existing) archives.

So i finally sat down this weekend and added that.

The code is not tested very well (it works for me but may not work for you) and has no ASDocs yet, so i release it as an alpha version, with the hope of massive bug feedback.. :)

Download: fzip_1_0_52_alpha.zip fzip.zip

New methods in class FZip:

  • addFile(name:String, date:Date, content:ByteArray)
  • addFileAt(index:uint, name:String, date:Date, content:ByteArray)
  • removeFileAt(index:uint)
  • serialize(stream:IDataOutput)

Sample code:

// Create file contents
var ba:ByteArray = new ByteArray();
ba.writeUTFBytes("Hello World!");
// Create ZIP archive and add file
var zip:FZip = new FZip();
zip.addFile("hello.txt", null, ba);
// Serialize ZIP into a new file
// (we use the Adobe AIR specific class FileStream here,
// but you can as well use ByteArray or anything that
// implements IDataOutput)
var file:File = File.applicationStorageDirectory;
file = file.resolvePath("hello.zip");
var stream:FileStream = new FileStream();
stream.open(file, FileMode.WRITE);
zip.serialize(stream);
stream.close();

FZip, AIRRemoteUpdater Upgraded for AIR Beta 2

Just a quick FYI: FZip and AIRRemoteUpdater upgrades for AIR Beta 2 are now available for download.

FZip now uses ByteArray.uncompress(CompressionAlgorithm.DEFLATE) instead of the now deprecated ByteArray.inflate(). I also tweaked FZip to throw an exception when a parsing error occurs and no event listener is registered for FZipErrorEvent.PARSE_ERROR events.

AIRRemoteUpdater now gets the local descriptor XML via Shell.shell.applicationDescriptor which was added in AIR Beta 2, and uses the upgraded FZip sources.

Enjoy, and please let me know if you run into any problems with this new release.

Automating remote software updates in Adobe AIR applications

I just released the first version of AIR Remote Updater, an AS3 class to automate remote software updates in Adobe AIR applications.

It transparently checks version numbers, downloads the .AIR installer file if needed and triggers the AIR-native update process.

It grabs the version number directly from the remote .AIR file without having to download the entire file, eliminating the potential error prone need of having to put a separate descriptor file online along with the .AIR installer file.

Background:

An .AIR installer file is a PKZIP archive containing metadata files along with the packaged application files. The files contained in a .AIR installer file are, in this order:

  1. /mimetype
  2. /META-INF/AIR/application.xml (contains version info)
  3. /META-INF/AIR/hash
  4. /META-INF/signatures.xml
  5. packaged application files

The file we are interested in, /META-INF/AIR/application.xml (the “application descriptor file” that contains the version number), is always the second file in the archive. AIR Remote Updater uses FZip to stream in the remote .AIR until (and only until) the application descriptor file has loaded. We can then close the stream, uncompress that file and extract the version number.

More info and download here:
http://codeazur.com.br/lab/airremoteupdater/