Aliaspooryorik
ColdFusion ORM Book

Create and Save a drawing with Flex and ColdFusion

I've created a prototype Flex 3 application which captures a drawing (or signature) that a user draws and saves it to the server using ColdFusion and Flex Remoting.

Most of the hard work was done by other bloggers and I've linked to them in the comments. So without further ado, here is the Flex code:


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init()">
<mx:Script>
<![CDATA[
/**
* References:
* http://www.sebastiaanholtrop.com/archives/3
* http://flash.tutsplus.com/tutorials/games/create-a-basic-drawing-application-in-flash/
* http://cookbooks.adobe.com/post_Save_a_local_image_file__JPEG_or_PNG__from_an_imag-8406.html
* http://livedocs.adobe.com/flex/3/html/help.html?content=controls_18.html
* **/



import mx.core.UIComponent;
import mx.graphics.ImageSnapshot;
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.graphics.codec.JPEGEncoder;
import mx.events.ColorPickerEvent;

/**
* instance variables
* */

[Bindable]
private var buttonsEnabled:Boolean = true;

[Bindable]
private var simpleDP:Array = ['0x000000', '0xFF0000', '0xFF8800',
'0xFFFF00', '0x88FF00', '0x00FF00', '0x00FF88', '0x00FFFF',
'0x0088FF', '0x0000FF', '0x8800FF', '0xFF00FF', '0xFFFFFF'];

private var pencilDraw:Sprite = new Sprite();
// pencil colour
private var activeColour:uint;
// pencil thickness
private var pencilThickness:int;

private function init():void
{
// set default pencil values
setStroke(10);
activeColour = simpleDP[0];

/* set remoteObject attributes */
amfService.endpoint = "http://{server.name}:{server.port}/flex2gateway/";

/* this is the dot path to the CFC from the webroot */
amfService.source = "FlexRemoting";

/* this is the servertype */
amfService.destination = "ColdFusion";

/* event listeners */
amfService.addEventListener(FaultEvent.FAULT, faultHandler);
amfService.addEventListener(ResultEvent.RESULT, resultHandler);

picture.addEventListener(MouseEvent.MOUSE_DOWN, startPencilTool);
picture.addEventListener(MouseEvent.MOUSE_UP, stopPencilTool);
}

private function grabScreen():ByteArray
{
return ImageSnapshot.captureImage(picture, 0, new JPEGEncoder()).data;
}
private function exportImageToJPG():void
{
buttonsEnabled = false;
var data:ByteArray = grabScreen();
amfService.saveAsImage(data);
}


/**
* remoting methods
* */

private function faultHandler(event:FaultEvent):void
{
Alert.show(event.message.toString(), "ERROR MESSAGE");
Alert.show(event.fault.toString(), "ERROR FAULT");
}
private function resultHandler(event:ResultEvent):void
{
showAlert(event.message.toString(), "ERROR MESSAGE");
}
private function showAlert(message:String, caption:String=""):void
{
if (caption.length==0)
{
Alert.show(message);
}
else
{
Alert.show(message, caption);
}
}

/**
* drawing methods
* */

private function drawPencilTool(e:MouseEvent):void
{
/* Draws a line from the current Mouse position to the moved Mouse position */
pencilDraw.graphics.lineTo(mouseX, mouseY);
}
private function stopPencilTool(e:MouseEvent):void
{
/* Stops the drawing */
picture.removeEventListener(MouseEvent.MOUSE_MOVE, drawPencilTool);
}
private function startPencilTool(e:MouseEvent):void
{
/* We add a new shape to draw always in top (in case of text, or eraser drawings) */
pencilDraw = new Sprite();
var uiComponent:UIComponent = new UIComponent();

/* add UIComponent to the canvas as a container for our sprite */
picture.addChild(uiComponent);

/* Add that shape to the board MovieClip */
uiComponent.addChild(pencilDraw);

/* Moves the Drawing Position to the Mouse Position */
pencilDraw.graphics.moveTo(mouseX, mouseY);

/* Sets the line thickness to the ShapeSize MovieClip size and sets its color to the current active color */
pencilDraw.graphics.lineStyle(pencilThickness, activeColour);

/* Adds a listener to the next function */
picture.addEventListener(MouseEvent.MOUSE_MOVE, drawPencilTool);
}
private function changeColour(e:ColorPickerEvent):void
{
activeColour = e.currentTarget.selectedItem;
}
private function setStroke(size:int):void
{
pencilThickness = size;
}
]]>

</mx:Script>
<mx:Canvas x="10" y="10" width="556" height="344" borderStyle="solid" borderThickness="2" borderColor="#001ABA" backgroundColor="#FFFFFF" id="picture">
</mx:Canvas>
<mx:Button x="465" y="362" label="Save & Send!" id="btnSave" click="exportImageToJPG()" enabled="{ buttonsEnabled }" />
<mx:RemoteObject
id="amfService">

<mx:method
name="saveAsImage"
result="resultHandler(event)"
fault="faultHandler(event)" />

</mx:RemoteObject>
<mx:ColorPicker id="cp" dataProvider="{simpleDP}" change="changeColour(event);" x="10" y="362"/>
<mx:Button x="40" y="362" label="Small" id="btnSmall" click="setStroke(2)"/>
<mx:Button x="105" y="362" label="Medium" id="btnMedium" click="setStroke(10)"/>
<mx:Button x="183" y="362" label="Big" id="btnLarge" click="setStroke(18)"/>
</mx:Application>

As you can see, the Flex code is set up to talk to ColdFusion using Flex Remoting, so here is the FlexRemoting.cfc


<cfcomponent output="false">

<cffunction
name="saveAsImage"
access="remote"
output="false"
returntype="void">


<cfargument name="data"
type="binary"
required="true">

    
<cfset var imagepath = GetDirectoryFromPath( GetCurrentTemplatePath() ) & CreateUUID() & ".jpg">

<cffile action="write"
file="#imagepath#"
output="#arguments.data#">


</cffunction>

</cfcomponent>

4 comments

  1. Thanks a lot for this example.
    It was very usefull to me.

    Comment by Vincent – February 13, 2010
  2. Hi,
    Is there an alternative to coldfusion here????

    Comment by ronnie – July 02, 2010
  3. @ronnie, I use ColdFusion which as you can see makes it very simple, but flex is sending binary data, so any half decent server side language should be able to process it.

    Comment by John Whish – July 02, 2010
  4. Thank's a lot for giving this example this example very helpfull to me thank's a lot

    Comment by sarath – August 17, 2010

Leave a comment

If you found this post useful, interesting or just plain wrong, let me know - I like feedback :)

Please note: If you haven't commented before, then your comments will be moderated before they are displayed.

Please subscribe me to any further comments
 

Search

Wish List

Found something helpful & want to say ’thanks‘? Then visit my Amazon Wish List :)

Categories

Recent Posts