« Flex Camp Italy Presentation Live Today! | Main | FlexCamp Presentation (part 2 of 3) : Pixel Bender »
FlexCamp Presentation (part 1 of 3) : FileReference load()
| By Rich Tretola | September 8, 2009 | |
| 11,477 views |
I gave a presentation for FlexCamp Italy over the weekend. The basics of the session was showing how to load an image from the desktop into the Flash Player, tweak the image with PixelBender, and finally save the image back to the desktop with no server required. Yes, that’s correct, as long as you have Flash Player 10, you will not need a server to load and save files via the Flash Player running in the web browser.

In part 1 we will discuss how to load a file into the Flash Player via the FileReference class. Part 2 will discuss how to use Pixel Bender filters, and finally in part 3 will discuss how to save the file back to the file system.
Click here to run the application (View source is enabled)
So, here is how it works. Lets review the code below.
Loading an Image into the Flash Player:
- On line 18, I create an instance of FileReference called loadFileRef.
- Within lines 57-60 (which is part of the init() function called on applicationComplete()) defines the eventListeners that will listen for SELECT, PROGRESS, COMPLETE, & IO_ERROR) for the loadFileRef instance.
- Line 141 includes a Button component that when clicked calls the browseAndUpload() method
- The browseAndUpload() method on line 74 does the following: resets the log text property, sets the image source to null, removes all existing image filters, and finally and most importantly calls the browse() method on the loadFileRef instance.
- Notice that the browse() method on line 78 accepts a variable named fileTypes which is defined on line 14. Passing this into a FileReference browse() method restricts the operating system’s file browser to the specific file types defined.
- Security Alert: The browse() method on the FileReference class must be called by direct user interaction (button click, etc). Calling the method programatically will result in a Flash Player security violation.
- Upon selection of an image, the SELECT eventListener is triggered. We have defined this listener to call the fileSelected() method located on line 82. This method does the following: logs some information about the selected file, creates a startTime time stamp, and finally calls the load() method which imports the selected file (an image in this case) to the Flash Player.
- While the file is being loaded, the PROGRESS evenListener is called providing feedback on progress. In this case, the eventListener we defined for this event, calls the loadProgress() method on line 90. The loadProgress() method sets the progressBar (that we have defined on line 156) to visible, then updates the progress information and label information.
- Assuming all is well, the COMPLETE listener will fire next which calls the loadCompleted() method we have defined on line 98. This method does the following: sets the image components source property to the data property of the loadFileRef instance (which now holds the image in a byteArray), resets the progressBar, sets the endTime, and logs the total time elapsed for the load process.
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 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" backgroundColor="0xFFFFFF" applicationComplete="init();" viewSourceURL="srcview/index.html"> <mx:Script> <![CDATA[ import mx.controls.Alert; import mx.formatters.NumberFormatter; import mx.graphics.codec.PNGEncoder; // encoder to create file to save private var png:PNGEncoder = new PNGEncoder(); // allowed file types private var fileTypes:FileFilter = new FileFilter("Image", "*.jpg;*.jpeg;*;*.gif;*.png;*"); // FileReference classes for upload and download [Bindable] private var loadFileRef:FileReference = new FileReference(); private var saveFileRef:FileReference = new FileReference(); // filter objects [Embed("filters/pixelate.pbj", mimeType="application/octet-stream")] private var PixelateFilterClass:Class; [Embed("filters/SmartNormalMap.pbj", mimeType="application/octet-stream")] private var SmartNormalMapFilterClass:Class; [Embed("filters/twirl.pbj", mimeType="application/octet-stream")] private var TwirlFilterClass:Class; [Embed("filters/ZoomBlurFocus.pbj", mimeType="application/octet-stream")] private var ZoomBlurFocusClass:Class; // Shaders private var pixelateShader:Shader; private var smartNormalMapShader:Shader; private var twirlShader:Shader; private var zoomBlurFocusShader:Shader; // ShaderFilters private var pixelateFilter:ShaderFilter; private var smartNormalMapFilter:ShaderFilter; private var twirlFilter:ShaderFilter; private var zoomBlurFocusFilter:ShaderFilter; // format file size private var numberFormatter:NumberFormatter = new NumberFormatter(); // timers to track upload time private var startTime:Date; private var endTime:Date; // call on applicationComplete private function init():void { // add event listeners for upload loadFileRef.addEventListener(Event.SELECT, fileSelected); loadFileRef.addEventListener(ProgressEvent.PROGRESS, loadProgress); loadFileRef.addEventListener(Event.COMPLETE, loadCompleted); loadFileRef.addEventListener(IOErrorEvent.IO_ERROR, ioerror); // create new shaders and filters pixelateShader = new Shader(new PixelateFilterClass() as ByteArray); pixelateFilter = new ShaderFilter(pixelateShader); smartNormalMapShader = new Shader(new SmartNormalMapFilterClass() as ByteArray); smartNormalMapFilter = new ShaderFilter(smartNormalMapShader); twirlShader = new Shader(new TwirlFilterClass() as ByteArray); twirlFilter = new ShaderFilter(twirlShader); zoomBlurFocusShader = new Shader(new ZoomBlurFocusClass() as ByteArray); zoomBlurFocusFilter = new ShaderFilter(zoomBlurFocusShader); } // launch the file system browse dialog and filter file types private function browseAndUpload():void { log.text=""; image.source=null; removeFilters(); loadFileRef.browse([fileTypes]); } // called after a file has been selected within the file system browser private function fileSelected(evt:Event):void { log.text += "file size: " + numberFormatter.format(loadFileRef.size) +" bytes\n"; log.text += "file name: " + loadFileRef.name +"\n"; startTime = new Date(); loadFileRef.load(); } // load progress captured for progress bar private function loadProgress(evt:ProgressEvent):void { progressBar.visible = true; progressBar.setProgress( Number(evt.bytesLoaded / evt.bytesTotal), 1 ); progressBar.label = numberFormatter.format(evt.bytesLoaded) + " of " + numberFormatter.format(evt.bytesTotal) + " bytes uploaded"; } // load has completed private function loadCompleted(evt:Event):void { image.source = loadFileRef.data; progressBar.setProgress(1,1); progressBar.visible = false; endTime = new Date(); log.text += "upload time: " + (endTime.time - startTime.time) + " milliseconds"; } // load error public function ioerror(evt:IOErrorEvent):void{ Alert.show(evt.text,"Error"); } // capture image and save back to client private function capture():void{ var bitmapData:BitmapData = new BitmapData(image.width, image.height); bitmapData.draw(image); var ba:ByteArray = png.encode(bitmapData); // split off the original extension and replace with png var ext:String = loadFileRef.name.split(".").pop(); saveFileRef.save(ba,loadFileRef.name.replace(ext,"png")); } // add PixelBender filter private function addFilter(filter:ShaderFilter):void{ var filters:Array = image.filters; filters.push(filter); image.filters = filters; } // remove all filters private function removeFilters():void{ image.filters = null; } // return true when image is available private function buttonsEnabled(bytes:ByteArray):Boolean{ if(bytes.length)return true; return false; } ]]> </mx:Script> <mx:HBox> <mx:Button label="Load file" click="browseAndUpload()"/> <mx:Button label="Save file" click="capture()" enabled="{buttonsEnabled(loadFileRef.data)}"/> <mx:Button label="Pixelate" click="addFilter(pixelateFilter)" enabled="{buttonsEnabled(loadFileRef.data)}"/> <mx:Button label="SmartNormalMap" click="addFilter(smartNormalMapFilter)" enabled="{buttonsEnabled(loadFileRef.data)}"/> <mx:Button label="Twirl" click="addFilter(twirlFilter)" enabled="{buttonsEnabled(loadFileRef.data)}"/> <mx:Button label="ZoomBlurFocus" click="addFilter(zoomBlurFocusFilter)" enabled="{buttonsEnabled(loadFileRef.data)}"/> <mx:Button label="Remove All Filters" click="removeFilters()" enabled="{buttonsEnabled(loadFileRef.data)}"/> </mx:HBox> <mx:TextArea id="log" width="700" height="60" /> <mx:ProgressBar id="progressBar" visible="false" mode="manual"/> <mx:Image id="image" maxHeight="600" maxWidth="800"/> </mx:Application> |
Part 2 will demonstrate how to use Pixel Bender filters to alter the image that we just loaded into the Flash Player.
Topics: Flash Player, Flex, Tutorials | 14 Comments »









September 8th, 2009 at 9:14 am
[...] flexcamp pixelblender http://blog.everythingflex.com/2009/09/08/flexcamp-presentation-filereference-load-part-1-of-3/ [...]
September 9th, 2009 at 12:25 am
Very nice, and pretty fast loading and saving images.
Do you know if its possible to apply some bender filter to an specific area? Thanks!
Reply to this comment
September 9th, 2009 at 7:52 am
[...] This post was mentioned on Twitter by Rich Tretola and maheshbabu. Rich Tretola said: Finished part 2 of my 3 part series, it will publish shortly, if you missed part 1, here it is http://bit.ly/IYr3c [...]
September 9th, 2009 at 8:02 am
[...] FlexCamp Presentation (part 1 of 3) : FileReference load() [...]
September 9th, 2009 at 5:51 pm
pretty fast loading. nice work. thanks
Reply to this comment
September 10th, 2009 at 8:01 am
[...] FlexCamp Presentation (part 1 of 3) : FileReference load() [...]
October 7th, 2009 at 3:52 am
nice one..but i need it in flex3…please help me
Reply to this comment
Rich Tretola Reply:
October 7th, 2009 at 10:37 am
The example is Flex 3.
Reply to this comment
October 8th, 2009 at 12:13 am
then i cannt access the ShaderFilter.it shows the following error
1046: Type was not found or was not a compile-time constant: ShaderFilter.
Reply to this comment
October 8th, 2009 at 1:19 am
i found due to sdk problem only i can’t load and save file in flex3..in my builder i am using sdk3… what can i do?
Reply to this comment
October 8th, 2009 at 8:49 am
Hey,
I’m getting “SecurityError: Error #2000: No active security context.” inside the load complete event handler when trying to access fileref.data
Reply to this comment
October 15th, 2009 at 10:56 pm
I am trying to post a file into a database with a C# web service. The column in the database is a VarBinary(MAX). It seems to save the data properly when I pass a straight-up byte array back and forth, but when I try to access it from my Flex 3 app, it throws an IOError #2032 Stream Error. The Image property is a byte array. Help!
Code that takes the data from the FileReference and calls the webservice are as follows:
private function fileRef_complete(evt:Event):void
{
projectVariables = ProjectVariables.getInstance();
message += ” (complete)”;
progressBar.setProgress(1,1);
progressBar.visible = false;
//Set up the Screenshot to pass into the web service
var screenShot:ScreenShotReturnObject = new ScreenShotReturnObject();
screenShot.ScreenShot = new ScreenShotObject();
screenShot.ScreenShot.DocumentationID = DocumentationID;
image = fileRef.data;
screenShot.ScreenShot.Image = image;
screenShot.ScreenShot.CreatedBy = projectVariables.GetUser().EmployeeID;
screenShot.ScreenShot.CreatedDate = new Date(“10/15/2009 07:08 PM”);
screenShot.ScreenShot.ModifiedBy = projectVariables.GetUser().EmployeeID;
screenShot.ScreenShot.ModifiedDate = new Date(“10/15/2009 07:08 PM”);
screenShot.ScreenShot.IsActive = true;
screenShot.ReferenceID = CallerEnum.BusinessAnalystDocumentationDetailsFileUpload;
//Now, we want to go ahead and upload the screenshot to the database
projectVariables.GetService().saveScreenshot(screenShot);
}
Reply to this comment
February 28th, 2010 at 1:31 am
The column in the database is a VarBinary(MAX). It seems to save the data properly when I pass a straight-up byte array back and forth,
Reply to this comment
March 28th, 2010 at 3:52 pm
[...] Chicago company called Humanized; I currently reside in San Francisco and work for Mozilla. …FlexCamp Presentation (part 1 of 3) : FileReference load …360Flex actionscript air air 2 android apple as3 books conference contest cookbook deeplinking [...]