ImageMagick – Let the magic begin



flash - Imagemagick

Often when i have looked at sites like zazzle, photofunia etc: it has amazed me so as to what the power of graphics in the hand of a programmer could do. so recently i thought of writing down this tutorial to help people understand how each field has its own strength.
This is all about Imagemagick coupled with flash actionscript. Being a actionscript developer i have found this a new field to venture into that makes flash coupled with imagemagick seamlessly the strongest competit
or on the web.

So lets get started on this journey together. First we get started with preparing our front end, and i choose flex.

Application demo

Get Adobe Flash player

Preparing the Front End:

Open up your flexBuilder and create a new flex project. I name mine as Imagemagickdemo.  Set up your project to publish for flash player 10.  If you use flex builder 3 you may want to check out how to change your flex sdk to work with flash player 10 .

Once your flex is ready jump into design view and pull in two buttons. Set labels as Browse and Sketch respectively. Below that set up a panel component. provide ids for the components as btnBrowse, btnSketch, pnl respectively.

Now jump into the code view. Here is my flex code.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init()" width="550" height="400">
<mx:Canvas top="20" bottom="20" left="20" right="20">
<mx:Panel layout="absolute" right="20" left="20" top="56" id="pnl" bottom="19">
<mx:Image width="100%" height="100%" id="img"/>
</mx:Panel>
<mx:Button x="40" y="10" label="Browse" id="btnBrowse" click="Selectfiles()"/>
<mx:Button x="142" y="10" label="Sketch" id="btnSketch" click="turnToSketch()"/>
</mx:Canvas>
<mx:Script>
<![CDATA[
import flash.net.FileReference;
import flash.net.Responder;
import flash.events.Event;
import flash.display.Loader;
import flash.display.LoaderInfo;
import mx.rpc.events.ResultEvent;
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import flash.net.NetConnection;
import mx.managers.CursorManager;
private var __fref:FileReference;
private var __loader:Loader;
private var conn:NetConnection;
private var magickResponder:Responder;
private var imageHolder:Image;
private function init():void
{
        conn = new NetConnection();
        conn.objectEncoding = ObjectEncoding.AMF3;
        conn.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onPermissionError);
        conn.connect("http://your-domain/amfphp/gateway.php");
        magickResponder = new Responder(onResult, onFault);
       
        __fref = new FileReference();
        __fref.addEventListener(Event.SELECT, onItemSelect);
        __fref.addEventListener(Event.CANCEL, onItemCancel);
        __fref.addEventListener(Event.COMPLETE, onItemComplete);
}
private function UIInit():void
{
        btnBrowse.enabled = true;
        btnSketch.enabled = false;      
}
private function Selectfiles():void
{
        __fref.browse();
}
private function onItemSelect(e:Event):void
{
        __fref.load();
}
private function onItemCancel(e:Event):void
{
       
}
private function onItemComplete(e:Event):void
{
        btnBrowse.enabled = false;
        btnSketch.enabled = true;
               
        __loader = new Loader();
        __loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
        __loader.loadBytes(__fref.data);
}
private function onComplete(e:Event):void
{
        if(pnl.numChildren > 0) pnl.removeChildAt(0);
        imageHolder = new Image();
        pnl.addChild(imageHolder);
        ImageResizer.ResizeImage(LoaderInfo(e.target).loader,pnl.width-50,pnl.height-50);
        imageHolder.addChild(LoaderInfo(e.target).loader);
}
private function turnToSketch():void
{
        conn.call("ImageKing.ConvertFunction", magickResponder,__fref.data);
        CursorManager.setBusyCursor();
}
private function onPermissionError(e:SecurityErrorEvent):void
{
               
}
// response handlers
private function onResult(e:*):void
{
        CursorManager.removeBusyCursor();
        UIInit();
        var resultImageLoader:Loader = new Loader();
        resultImageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
        resultImageLoader.loadBytes(ByteArray(e));
}
private function onFault(e:*):void
{
        Alert.show(e);
}
]]>
</mx:Script>
</mx:Application>

The data property of the filereference object holds the byte array.Now that we know how we select the file and render it to screen as image data, we will proceed with sending this data to server for processing.
But first let me share a few more things:
1. I use ImageResizer class to resize the images being rendered by aspect so that they fit in my canvas.
you can get the class file here.

2. Note that i use a Image class object to render my image to th epanel. This is because the Panel is a UICompenent and thus cannot render the Loader which s not a UIComponent.

Finally we call the turnToSketch() method to send the data to server.

conn.call("ImageKing.ConvertFunction", magickResponder,__fref.data);
CursorManager.setBusyCursor();
Note:  The CursorManager.setBusyCursor() method is optional.

We will discuss the remaining of front end code, namely the result handler after we return from the backend code.

Preparing the Back End:

I asume that the reader knows about setting up amfphp on the server. If not  i recommend this article to help you catch up. Or if you have read the link about setting up amfphp flash remoting in the previous section you would already be aware of it.

Now to the back end… :)

amfphp services for flash/flex etc are typically php classes. How we write them ?   well we are going to see shortly :) . Just as before let me first post the code then get on with the explaination. So here is the php class.

<?php
class ImageKing
{

var $output_dir = "trash";
var $server_url = "http://your-domain/amfphp/services";


var $default;

function  ImageKing(){
$this->methodTable = array(
"Convert" => array(
"description" => "sketches the image",
"access" => "remote", // available values are private, public, remote
"arguments" => array ("arg1")
)
);
}  

function ConvertFunction($ba,$compressed=false)
{
$data = $ba->data;

if(!file_exists($this->output_dir) || !is_writeable($this->output_dir))
trigger_error ("please create a 'temp' directory first with write access", E_USER_ERROR);


if($compressed)
{
if(function_exists(gzuncompress))
{
$data = gzuncompress($data);
} else {
trigger_error ("gzuncompress method does not exists, please send uncompressed data", E_USER_ERROR);
}
}

$ext = '.jpg';
$file = tempnam($this->output_dir, 'flashvision').$ext;


file_put_contents($file, $data);

$command = 'convert '.$file.' -charcoal 5 '.$file;
//$command = 'convert '.$file.$ext.' -matte -background none  -wave 10x75  '.$file.'.png';
passthru($command);

return new ByteArray(file_get_contents($server_url.'/'.$file));
}

}
?>

as you can see.. the two variables :

var $output_dir = "trash";
var $server_url = "http://your-domain/amfphp/services";

are used as private variables of the ImageKing class. This is why we use “->”operator to access them. Since we are just concerned with the Convert class lets check that out. :)

Now let me recall from the front end code:

conn.call("ImageKing.ConvertFunction", magickResponder,__fref.data);

We call the Convert method of the ImageKing class by passing the byte data of the selected image as parameter and we set up Responder magickResponder to react to the incoming result.

The Convert function in php thus accepts the byte data object in $ba. It then extracts the actual byte array from it like this: $data = $ba->data;

Next these are come checks to ensure if data is in compressed format we will use gzip in php to uncompress it before reading. else we create a temporary file,

$ext = '.jpg';
$file = tempnam($this->output_dir, 'flashvision').$ext;

for sake of simplicity i store my extension as “.jpg” as fixed.
Now we dump the byte array into the temp file:

file_put_contents($file, $data);

Now time to do the magick :)

‘abra ca dabra’…

$command = 'convert '.$file.' -charcoal 5 '.$file;

This code calls Image magick  (if installed in your server) and applies a charcoal effect on the image file. then we use amfphp’s byte array support to return a byte array of the converted image to our waiting client.

Back to the Front End:

private function onResult(e:*):void
{
CursorManager.removeBusyCursor();
UIInit();
var resultImageLoader:Loader = new Loader();
resultImageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
resultImageLoader.loadBytes(ByteArray(e));
}

In the result handler function , flash recieves the byte array and creates a Loader object to render it. we again use the loadbytes() method of the loader class to read the byte array as image data and then add it to the panel, replacing the previous normal image. I bet you can achieve more speed with a dedicated server and compressed byte array to start with.
Get full source code here

Popularity: 22% [?]




August 8, 2009  Tags: ,   Posted in: Actionscript 3.0

40 Responses

  1. money making opportunities from - February 26, 2011

    Thank you for posting this. I fully agree with your opinion.

  2. Luncies - March 9, 2011

    Affordable Web Hosting…

    [...]below you’ll find the link to some sites that we think you should visit[...]…

  3. BJ Novak - March 10, 2011

    Double strollers…

    [...]the time to read or visit the content or sites we have linked to below the[...]…

  4. fresno limos - March 10, 2011

    Fantastic Post…

    [...]is always a good read, take a look now to see if there is anything new and let me know if you[...]…

  5. hampton bay ceiling fan parts - March 10, 2011

    Quit Smoking Weed…

    [...]below you’ll find the link to some sites that we think you should visit[...]…

  6. http://www.agreensupply.com/ - March 11, 2011

    Find LED Christmas Lights by Color…

    [...]the time for you to study or go to the content or web-sites we’ve linked to beneath the[...]…

  7. Student Loan Consolidation News - March 11, 2011

    First student loan…

    [...]the time to read or visit the content or sites we have linked to below the[...]…

  8. Flax Seeds Weight Loss - March 12, 2011

    Flax Seeds Benefit…

    [...] below you’ll find the link to some sites that we think you should visit. Posted in [...]…

  9. Strip That Fat - March 12, 2011

    Eat Stop Eat…

    [...]the time to read the places we have pointed out below[...]…

  10. הכרויות בטלפון - March 13, 2011

    הכרויות בטלפון…

    [...]below you’ll find the link to some sites that we think you should visit[...]…

  11. How to get 360 waves - March 14, 2011

    Sites we Like…

    [...] Every month we choose websites that we read. Listed below are the newest websites that we picked [...]…

  12. Sensa Reviews - March 14, 2011

    Sensa Scam…

    [...]below you’ll find the link to some sites that we think you should visit[...]…

  13. kaddish - March 15, 2011

    Chan luu…

    [...]below you’ll find the link to some sites that we think you should visit[...]…

  14. portable air conditioning units reviews - March 15, 2011

    portable air conditioning units…

    [...]below you’ll find the link to some sites that we think you should visit[...]…

  15. portable air conditioning units for sale - March 16, 2011

    portable air conditioner…

    [...]the time to read or visit the content or sites we have linked to below the[...]…

  16. new fat loss foods - March 16, 2011

    Amazing site…

    [...]the time to read or visit the content or sites we have linked to below the[...]…

  17. credit card processing - March 17, 2011

    how to tone your stomach…

    [...]the time to check out sites we have linked to underneath the[...]…

  18. Yankee Candles Cheap - March 17, 2011

    Basketball Jerseys…

    [...]the time to read or visit the content or sites we have linked to below the[...]…

  19. sacar musculos rapidamente - March 17, 2011

    Venta y Alquiler de Barcos…

    [...]the time to read or visit the content or sites we have linked to below the[...]…

  20. Small business marketing consultant - March 18, 2011

    tinnitus treatment…

    [...]I am normally looking for value. This article makes so much. just want to keep tabs on[...]…

  21. Car Shipping Company - March 19, 2011

    Car Shipping…

    [...]most people recognized your web site had been stated on much of our embroidering design web page[...]…

  22. buy viagra - March 20, 2011

    Hello…

    This website is the most excellent website….

  23. Mens Watches - March 21, 2011

    thomas sabo jewellery…

    [...]the time to read or visit the content or sites we have linked to below the[...]…

  24. margarita maker margaritaville - March 21, 2011

    margarita maker machine…

    [...]below you’ll find the link to some sites that we think you should visit[...]…

  25. the truth about six pack abs package - March 22, 2011

    how to burn stomach fat…

    [...]the time to read or visit the content or sites we have linked to below the[...]…

  26. Scary Maze - March 22, 2011

    Scary Maze Game…

    [...]below you’ll find the link to some sites that we think you should visit[...]…

  27. New Garbage Trucks For Sale - March 23, 2011

    New Trash Truck…

    [...]many of us observed your web site has been explained in our screen producing website[...]…

  28. Garbage Trucks - March 23, 2011

    Garbage Truck…

    [...]a post relating for your site has become released in the exact location in the list above[...]…

  29. Trash Truck Buyers GUide - March 23, 2011

    Used Trash Truck…

    [...]all of us found your site appeared to be stated on much of our embroidery design web site noticed your website ended up being stated in your website[...]…

  30. Detroit DUI Lawyer - March 23, 2011

    Find an Attorney…

    [...]below you shall discover the address to many websites that I believe you should see[...]…

  31. Forth Worth Bankruptcy Lawyers - March 24, 2011

    Get a Lawyer…

    [...]below you’ll find the URL to a couple sites that we think you should visit[...]…

  32. order viagra - March 25, 2011

    Hello!…

    [...]You made some clear points there[...]…

  33. the diet solution program - March 31, 2011

    the diet solution program…

    Thanks for the excellent blog post….

  34. viagra - March 31, 2011

    Hello…

    [...]This website is the most excellent website.[...]…

  35. Approved - April 1, 2011

    [...]the time to read or visit the content or sites we have linked to below the[...]…

  36. Approved - April 1, 2011

    [...]below that are definitely worth checking out[...]…

  37. Anonymous - April 2, 2011

    Fat burning foods for men…

    [...]the time to read or visit the content or sites we have linked to below the[...]…

  38. Hunstanton - April 6, 2011

    Hunstanton…

    Trackback, I have linked to your site, thank you!…

  39. term life insurance - April 7, 2011

    outdoor furniture…

    [...]below you’ll find the link to some sites that we think you should visit[...]…

  40. market place - April 7, 2011

    market place…

    Trackback, I have linked to your site, thank you!…

Leave a Reply