SYS-CON Media
 Register Now!
Save $200
Register before October 17th to SAVE! ... and also receive a FREE copy of the Best-Selling AJAX Book, a $119 Value!
Untitled Document
2008 East
Platinum Sponsor
Untitled Document
2008 East Gold Sponsors
Untitled Document
2008 East Exhibitors
Untitled Document
2008 East Media Sponsors
Untitled Document
2008 Association Sponsor
SYS-CON Media
2007 West Sponsors
Goingtomeet.com Conference Directory
SYS-CON Media
2007 East Sponsors
Untitled Document
2008 SYS-CON Events

Can't Miss RSS Feed
Subscribe to the AJAXWorld.com RSS Feed & Get All The Conference News As It Happens!

2008: Decision Year for RIAs - October 20-22, 2008 San Jose


Creating a Flex 2 Signature Grabber
My MAXUP Experience

By the time you read this, another MAX will be in the history books. In fact, with a record attendance of around 3,500 developers and designers, this MAX in Vegas will also be in the record books.

Along with the usual great conference sessions, this year there was a special event referred to as the "BarCamp - The unconference event" called MAXUP. I presented a MAXUP demo, A Flex 2 Signature Panel at MAXUP, where I showed the audience how easy it was to combine a Flex 2 UI for capturing a mouse-created signature with the ActionSript 3 Drawing API and a remote object call to a ColdFusion component. Leveraging work that James Ward blogged about on cayambe.com, I retooled the back-end as a ColdFusion CFC (I make remote object calls to the CFC's functions), and made some minor UI changes to create a signature panel that could be used for online NDA agreements or e-signatures.

Adobe Flex 2 Builder allowed me to lay out very quickly a simple UI where a user can use a mouse (or even better a drawing pen) to write out messages (See Figure 1).

The signature pad captures a visitor's IP address via a remote object call to a CFC method getVisitorIP() during the Flex application's initialize event:

MXML:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" initialize=" roSign.getVisitorIP()"
creationComplete="setColor()" styleName="plain" viewSourceURL="srcview/index.html" horizontalAlign="center"
verticalAlign="top">

<mx:RemoteObject id="roSign"
destination="ColdFusion"
source="flex2_training.components.signature"
fault="mx.controls.Alert.show(event.fault.faultDetail.toString(), 'Alert');"
showBusyCursor="true">
<mx:method name="getVisitorIP" result="my_IP_handler(event.result)"/>
<mx:method name="doUpload" result="my_CFC_handler(event.result)"/>
</mx:RemoteObject>

CFC:
<cffunction name="getVisitorIP" displayname=
"Get IP Address" hint="Returns Visitor's' IP address" access="remote" returntype="string">
<cfset sIP = "#CGI.Remote_Addr#">
<cfreturn sIP />
</cffunction>

Clicking the 'Accept' button triggers the click event that calls the remote object doUpload and corresponding CFC method:

MXML:
<mx:RemoteObject id="roSign"
destination="ColdFusion"
source="flex2_training.components.signature"
fault="mx.controls.Alert.show(event.fault.faultDetail.toString(), 'Alert');"
showBusyCursor="true">
<mx:method name="getVisitorIP" result="my_IP_handler(event.result)"/>
<mx:method name="doUpload" result="my_CFC_handler(event.result)"/>
</mx:RemoteObject>

<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
import flash.events.Event;

private var sIP:String;
private function doSave():void {
var bd:BitmapData = new BitmapData(canvas.width,canvas.height);
bd.draw(canvas);
var ba:ByteArray = PNGEnc.encode(bd); // See the PNGEnc.as code
roSign.doUpload(ba,sIP); // pass the ByteArray and the Visitor's IP address
}
]]>
</mx:Script>
CFC:
<cffunction name="doUpload" displayname=
"Save Signature" hint="Saves a PNG Signature" access="remote" output="false" returntype="any">
<cfargument name="sigbytes" required="true" type="binary">
<cfargument name="ip_suffix" required="true" type="string">
<cfscript>
var myUUID = "";
    var SigFileName = "";
</cfscript>
<!--- create a FileOutputStream --->
<cfobject type="java" action="CREATE" class="java.io.FileOutputStream" name="oStream">
<cfscript>
    myUUID = CreateUUID(); // create a unique id

// call init method, passing in the full path to the desired jpg
oStream.init(expandPath("../converted_pngs/signature_#arguments.ip_suffix#_#myUUID#.png"));
oStream.write(arguments.sigbytes);
oStream.close();

SigFileName = getSigFileName("#arguments.ip_suffix#_#myUUID#");
</cfscript>
<cfreturn SigFileName />
</cffunction>

Once the doUpload method is complete, the event.result is returned (the dynamic file name [including both an IP address and a UUID] of the stored PNG image file) and assigned to a Flex string variable, SigFileName:

MXML:
<mx:Script>
<![CDATA[
........ abbreviated for space saving ........
    private var SigFileName:String;

private function my_CFC_handler(result:Object):void {
SigFileName = result.toString();
btnView.enabled = true;
}
]]>
</mx:Script>

Clicking on the 'View' button triggers the click event and the function doView(), which opens the page and the saved PNG image as shown in Figure 2:

MXML:
<mx:Script>
<![CDATA[
........ abbreviated for space saving ........

private function doView():void {
var u:URLRequest = new URLRequest("../welcome.cfm?sig=" + SigFileName + ".png");
navigateToURL(u,"_self");
}
]]>
</mx:Script>

The complete code listing is available at: http://webcfmx.no-ip.info/flextraining/signature/bin/srcview/index.html

PNGEnc.as:
package {

    import flash.geom.*;
    import flash.display.*;
    import flash.utils.*;

    public class PNGEnc {

    public static function encode(img:BitmapData):ByteArray {
      // Create output byte array
      var png:ByteArray = new ByteArray();
      // Write PNG signature
      png.writeUnsignedInt(0x89504e47);
      png.writeUnsignedInt(0x0D0A1A0A);
      // Build IHDR chunk
      var IHDR:ByteArray = new ByteArray();
      IHDR.writeInt(img.width);
      IHDR.writeInt(img.height);
      IHDR.writeUnsignedInt(0x08060000); // 32bit RGBA
      IHDR.writeByte(0);
      writeChunk(png,0x49484452,IHDR);
      // Build IDAT chunk
      var IDAT:ByteArray= new ByteArray();
      for(var i:int=0;i < img.height;i++) {
        // no filter
        IDAT.writeByte(0);
        var p:uint;
        if ( !img.transparent ) {
          for(var j:int=0;j < img.width;j++) {
          p = img.getPixel(j,i);
          IDAT.writeUnsignedInt(
            uint(((p&0xFFFFFF) << 8)|0xFF));
          }
        } else {
        for(var k:int=0;k < img.width;k++) {
        p = img.getPixel32(k,i);
        IDAT.writeUnsignedInt(
          uint(((p&0xFFFFFF) << 8)|
          (p>>>24)));
        }
      }
    }
    IDAT.compress();
    writeChunk(png,0x49444154,IDAT);
    // Build IEND chunk
    writeChunk(png,0x49454E44,null);
    // return PNG
    return png;
    }

    private static var crcTable:Array;
    private static var crcTableComputed:Boolean = false;

    private static function writeChunk(png:ByteArray,
      type:uint, data:ByteArray):void {
    if (!crcTableComputed) {
      crcTableComputed = true;
      crcTable = [];
      for (var n:uint = 0; n < 256; n++) {
        var c:uint = n;
        for (var k:uint = 0; k < 8; k++) {
        if (c & 1) {
          c = uint(uint(0xedb88320) ^
            uint(c >>> 1));
         } else {
            c = uint(c >>> 1);
         }
         }
         crcTable[n] = c;
      }
    }
    var len:uint = 0;
    if (data != null) {
      len = data.length;
    }
    png.writeUnsignedInt(len);
    var p:uint = png.position;
    png.writeUnsignedInt(type);
    if ( data != null ) {
      png.writeBytes(data);
    }
    var e:uint = png.position;
    png.position = p;
    var d:uint = 0xffffffff;
    for (var i:int = 0; i < (e-p); i++) {
      d = uint(crcTable[
        (d ^ png.readUnsignedByte()) &
        uint(0xff)] ^ uint(d >>> 8));
    }
    d = uint(d^uint(0xffffffff));
    png.position = e;
    png.writeUnsignedInt(d);
      }
    }
}

MAXUP was a great success. Although somewhat nervous before my presentation, I was grinning ear-to-ear afterwards from Adobe's Ted Patrick's encouragement. He said, "Mike, I like the way you used AMF to pass the byte-array to the server-side code." Thanks, Ted. (Figure 3)

Reflecting on how much easier it was to create this example compared to the two-month-long project of doing it with the Flash 7 IDE/Flex 1.5/CFMX 6.1/Apache Batik, I am simply amazed by Flex 2's versatility and efficiency in getting the job done quickly. If you still haven't had a chance to try out the Flex 2-CFMX 7.0.2 dynamic duo, I hope this example helps lure you in a bit further.

About Michael Givens
Mike Givens is the CTO of U Saw It Enterprises, a Web technology consulting firm based in Marietta, GA. He is an Adobe Corporate Champion known to share his experience and evangelism of all things Adobe. Certified in both ColdFusion 5 and as an Advanced CFMX Developer, he has been using ColdFusion since the days of Allaire Spectra. For the last 11 years, he has been seen with his head down - deep in the code.

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1

Great Article! I've always thought it'd be a nice feature to capture someones signature digitally. I had no idea it would be that easy, relatively speaking. Thanks for the post.


Latest AJAXWorld RIA Stories
Containers and Kubernetes allow for code portability across on-premise VMs, bare metal, or multiple cloud provider environments. Yet, despite this portability promise, developers may include configuration and application definitions that constrain or even eliminate application po...
Enterprises are striving to become digital businesses for differentiated innovation and customer-centricity. Traditionally, they focused on digitizing processes and paper workflow. To be a disruptor and compete against new players, they need to gain insight into business data and...
Digital Transformation: Preparing Cloud & IoT Security for the Age of Artificial Intelligence. As automation and artificial intelligence (AI) power solution development and delivery, many businesses need to build backend cloud capabilities. Well-poised organizations, marketing sm...
DXWorldEXPO LLC announced today that Ed Featherston has been named the "Tech Chair" of "FinTechEXPO - New York Blockchain Event" of CloudEXPO's 10-Year Anniversary Event which will take place on November 12-13, 2018 in New York City. CloudEXPO | DXWorldEXPO New York will present ...
Chris Matthieu is the President & CEO of Computes, inc. He brings 30 years of experience in development and launches of disruptive technologies to create new market opportunities as well as enhance enterprise product portfolios with emerging technologies. His most recent venture ...
Untitled Document

Call 201 802-3020 or Click Here to Save $200!

Register Today and
Save $200

Your registrations includes: Golden Pass Delegates will receive full conference access on October 20-22, 2008 including: Lunch and Coffee Breaks, Collectible Bag and Archives of all sessions on DVD. Includes access to all Conference Sessions including the Technical Sessions, Exhibits, Keynotes, Vendor Technology Presentations, and Power Panels.


Sponsorship Opportunities

AJAXWorld offers the undisputed best platform to position your company as a leading vendor in the fast-emerging marketplace for AJAX and Enterprise Web 2.0.


Please call
(201)802-3020


Who Should Attend?

 CTOs & VPs of Engineering
 Directors of Technology
 Sr. User Interface Architects
 Front-End Engineers
 VCs & Industry Analysts
 Directors of Business Development
 Software Engineers
 Senior Architects
 Application Programmers & Software Developers
 Project Managers
 Web Programmers & Designers
 Companies & Organizations that need to stay in
  front of the latest Web technology

AJAXWorld Security Bootcamp

Introducing at AJAXWorld RIA Conference 2008 West the world's first-ever full, one-day immersive "AJAX Security Bootcamp" - led by one of the world's foremost AJAX security experts and teachers, HP's Billy Hoffman.

View the full one-day schedule



AJAXWorld 2008 West - Tracks

Track 01: Enterprise RIAs
Track 02: Frameworks & Toolkits
Track 03: Web 2.0 & Mashups
Track 04: Hot Topics
Track 05: The Future of the Web
Track 06: iPhone Developer Summit



Brought To You By:

AJAXWorld Magazine is the pre-eminent independent vendor-neutral resource for the fastest growing new segment of the software business: entirely Web-based applications and experiences.

Download the Latest Issue!

AJAXWorld Webcasts



SYS-CON EVENTS


AJAXWorld Keynotes & Power Panels

2008 SYS-CON TV Keynotes: Can We Fix the Web? By Douglas Crockford - by Douglas Crockford
2008 SYS-CON TV Keynotes: 2008: The Year of the RIA - by Anthony Franco
2008 SYS-CON TV Power Panel: The Business Value of RIAs
2008 SYS-CON TV Power Panel: What Lies Beyond AJAX
2007 SYS-CON TV Keynotes: Why Web 2.0 for the Enterprise Is Far More Than Just a Facelift - by Ted Farrell
2007 SYS-CON TV Keynotes: Fueling the Next Generation Web: A Peek Behind the Green Curtain - by Bob Brewin
2007 SYS-CON TV Keynotes: AJAX in the Balance - by Joe Stagner

AJAXWorld Sessions on SYS-CON.TV

· Bill Scott - Yahoo! UI Library
· David Heinemeier Hansson - AJAX on Rails
· Jesse James Garrett - Elements of User Experience
· Dion Hinchcliffe - Real World AJAX
· Eric Miraglia - Open Source AJAX Development
· Paul Rademacher - Mashing Up Your Web Application
· Adam Sah - Google Gadgets
· Doug Crockford - An Introduction to JavaScript
· David Linthicum - Enterprise Web 2.0
· Patrick Grady - The Imagination & Experience Web

AJAXWorld...All The AJAX Rock Stars in One Spot!


Past Events Archive

SOAWorld Conference & Expo 2008 East
soa2008east.sys-con.com
Virtualization Conference & Expo 2008 East
virt2008east.sys-con.com
AJAXWorld 2008 Conference & Expo East
ajaxmar08.sys-con.com
SOAWorld Conference & Expo 2007 West
www.soaworld2007.com
Virtualization Conference & Expo 2007 West
virt2007west.sys-con.com
AJAXWorld 2007 Conference & Expo West
ajaxoct07.sys-con.com
SOAWorld Conference & Expo 2007 East
soa2007east.sys-con.com
Virtualization Conference & Expo 2007 East
virt2007east.sys-con.com
AJAXWorld 2007 Conference & Expo East
ajaxmarch07.sys-con.com
Other SYS-CON Events
events.sys-con.com

Join Over 10,000 Early AJAX Adopters
Who Have Attended AJAXWorld
• A&R Edelman
• Academic Enterprise
• Accoona Corp [2 delegates]
• Acxiom
• Adams Capital Management
• Adaptive Edge
• Adaptive Path
• Adobe Systems Incorporated [21 delegates]
• Adobe Systems Romania
• Ajax13
• All Risks, Ltd.
• alliance
• Alliance For Community Care
• AlphaDetail Inc
• Altera Corporation
• Amazon.com [6 delegates]
• Appeon Corporation [2 delegates]
• Apple Computer [5 delegates]
• Apress [3 delegates]
• Arkivio
• ASA
• Astute Solutions
• Avaya Inc [2 delegates]
• Avenda Systems
• Avenue A | Razorfish [3 delegates]
• Axcella, LLC [2 delegates]
• Aximsoft
• Azimyth
• Backbase USA Inc. [4 delegates]
• BAE Systems [2 delegates]
• Bank of America [2 delegates]
• Barkley Evergreen & Partners Interactive
• Bayview Financial [2 delegates]
• BEA Systems [3 delegates]
• Billeo
• BMC Software, Inc. [2 delegates]
• Borland Software Corporation
• Bradford Technologies, Inc [2 delegates]
• Brilliance
• Brocade Communications Systems, Inc. [2 delegates]
• Brookside Capital LLC
• Brulant
• Bungee Labs, Inc [6 delegates]
• Bureau of Labor Statistics
• BUZ Interactive
• Cadena Software
• Calix Networks
• Callidus Software [2 delegates]
• Cambia Security
• Carnegie Mellon West
• Cautella, Inc.
• CBSA
• Celequest [3 delegates]
• Change Vision, Inc.
• Charles E. Kenney, CPA
• Charles Schwab & Co., Inc. [8 delegates]

   read more...


ADVERTISE   |   MAGAZINE SUBSCRIPTIONS   |   FREE BREAKING-NEWSLETTERS!   |   SYS-CON.TV   |   BLOG-N-PLAY!   |   WEBCAST   |   EDUCATION   |   RESEARCH

.NET Developer's Journal - .NETDJ   |   ColdFusion Developer's Journal - CFDJ   |   Eclipse Developer's Journal - EDJ   |   Enterprise Open Source Magazine - EOS
Open Web Developer's Journal - OPEN WEB   |   iPhone Developer's Journal - iPHONE   |   Virtualization - Virtualization   |   Java Developer's Journal - JDJ   |   Linux.SYS-CON.com
PowerBuilder Developer's Journal - PBDJ   |   SEO / SEM Journal - SJ   |   SOAWorld Magazine - SOAWM   |   IT Solutions Guide - ITSG   |   Symbian Developer's Journal - SDJ
WebLogic Developer's Journal - WLDJ   |   WebSphere Journal - WJ   |   Wireless Business & Technology - WBT   |   XML-Journal - XMLJ   |   Internet Video - iTV
Flex Developer's Journal - Flex   |   AJAXWorld Magazine - AWM   |   Silverlight Developer's Journal - SLDJ   |   PHP.SYS-CON.com   |   Web 2.0 Journal - WEB2

SYS-CON MEDIA:   ABOUT US   |   CONTACT US   |   COMPANY NEWS   |   CAREERS   |   SITE MAP
SYS-CON EVENTS  |  AJAXWorld Conference & Expo  |  iPhone Developer Summit  |  OpenWeb Developer Summit  |  SOA World Conference & Expo  |  Virtualization Conference & Expo
INTERNATIONAL SITES:   India  |  U.K.  |  Canada  |  Germany  |  France  |  Australia  |  Italy  |  Spain  |  Netherlands  |  Brazil  |  Belgium
 Terms of Use & Our Privacy Statement     About Newsfeeds / Video Feeds
Copyright ©1994-2008 SYS-CON Publications, Inc. All Rights Reserved. All marks are trademarks of SYS-CON Media.
Reproduction in whole or in part in any form or medium without express written permission of SYS-CON Publications, Inc. is prohibited.