3. Flex
Ok, first of all let's see at the final swf file (right click to display the source):
And this is the .mxml file I used (see in a new window):
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:display="flash.display.*" xmlns:ns1="http://www.sephiroth.it/2006/mxml"> <mx:RemoteObject id="service" showBusyCursor="true" destination="amfphp" fault="faultHandler(event)" source="tutorials.amfphp_bytearray.SaveJPEG"> <mx:method name="SaveAsJPEG" result="savejpeg_resultHandler(event)" /> <mx:method name="SaveAsByteArray" result="savebyte_resultHandler(event)" /> </mx:RemoteObject> <mx:Style> NumericPopUp { slider-border-style:solid; slider-border-color:#999999; slider-background-color:#EBEBEB; direction:horizontal; } Application { background-color: #FFFFFF; } </mx:Style> <mx:Script> <![CDATA[ import mx.core.UIComponent; import mx.controls.Alert; import mx.controls.SWFLoader; import com.adobe.images.JPGEncoder; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; private var send_compressed:Boolean = false; // send always uncompressed bytearrays (i.e. your server doesn not support "gzuncompress") private var encoder:JPGEncoder; /** * Default handler for the remote SaveAsJPEG function */ private function savejpeg_resultHandler(event:ResultEvent):void { if(event.result || event.result is String) { var path:String = event.result as String; trace(path); var swf_loader:SWFLoader = preview_box.getChildByName("preview") as SWFLoader; swf_loader.showBusyCursor = true; swf_loader.load(path + "?rand=" + new Date().getTime()); image_size.text = "Loading..."; } } /** * Default handler for the remote SaveAsByteArray function */ private function savebyte_resultHandler(event:ResultEvent):void { var ba:ByteArray = event.result as ByteArray; var ui_loader:UIComponent = preview_box.getChildByName("preview") as UIComponent; image_size.text = 'ByteArray size: ' + Math.round(((ba.length/4)/1024)*100)/100 + ' Kb' try { ba.uncompress(); } catch(err:Error) { } var data:BitmapData = new BitmapData(original_image.width, original_image.height, false, 0); var bmp:Bitmap = new Bitmap(data); bmp.name = "image"; data.setPixels(data.rect, ba); ui_loader.addChild(new Bitmap(data)); ui_loader.width = data.width; ui_loader.height = data.height; } /** * Default fault handler */ private function faultHandler(event:FaultEvent):void { Alert.show(event.fault.faultString, "Error: " + event.fault.faultCode); trace(event.fault.message); } /** * Save the image using the JPEGEncoder class */ private function saveJpegHandler(event:MouseEvent):void { removeImages(); var swf_loader:SWFLoader = new SWFLoader(); swf_loader.autoLoad = true; swf_loader.name = "preview"; swf_loader.addEventListener(Event.COMPLETE, function(event:Event):void { image_size.text = 'Image size: ' + (SWFLoader(event.target).bytesTotal/1024).toPrecision(3) + ' Kb' }); preview_box.addChildAt(swf_loader, 0); var bmpdata:BitmapData = Bitmap(original_image.content).bitmapData; var ba:ByteArray; encoder = new JPGEncoder(jpeg_quality.value); ba = encoder.encode( bmpdata ); if(send_compressed) ba.compress(); service.getOperation("SaveAsJPEG").send(ba, send_compressed); image_size.text = "Sending..." } /** * Save the image using only ByteArray derived from * BitmapData.getPixels */ private function saveByteHandler(event:MouseEvent):void { removeImages(); var ui_loader:UIComponent = new UIComponent(); ui_loader.name = "preview"; preview_box.addChildAt(ui_loader, 0); var bmpdata:BitmapData = Bitmap(original_image.content).bitmapData; var arr:ByteArray = Bitmap(original_image.content).bitmapData.getPixels(new Rectangle(0,0,bmpdata.width, bmpdata.height)); if(send_compressed) arr.compress(); arr.position = 0; service.getOperation("SaveAsByteArray").send(arr, send_compressed); image_size.text = "Sending..." } private function removeImages():void { if(preview_box.getChildByName("preview")) preview_box.removeChild(preview_box.getChildByName("preview")); image_size.text = ""; } ]]> </mx:Script> <mx:VBox left="5" top="5" right="5" bottom="5"> <ns1:LabelledBox title="Original Image" direction="horizontal" paddingBottom="20" paddingLeft="20" paddingRight="20" paddingTop="20" labelPlacement="left" labelPadding="10" cornerRadius="5" id="original_box"> <mx:Image x="10" y="33" source="@Embed('images/284541843_b77b917989[1].jpg')" id="original_image"/> <mx:Grid x="269" y="33"> <mx:GridRow width="100%" height="100%"> <mx:GridItem width="100%" height="100%" verticalAlign="middle"> <mx:Label text="Jpeg quality"/> </mx:GridItem> <mx:GridItem width="100%" height="100%" verticalAlign="middle"> <ns1:NumericPopUp id="jpeg_quality" minimum="1" maximum="100" stepSize="1" value="50" direction="horizontal"> </ns1:NumericPopUp> </mx:GridItem> </mx:GridRow> <mx:GridRow width="100%" height="100%"> <mx:GridItem width="100%" height="100%"> </mx:GridItem> <mx:GridItem width="100%" height="100%" verticalAlign="middle"> <mx:Button label="Save as Jpeg" click="saveJpegHandler(event)" width="100%"/> </mx:GridItem> </mx:GridRow> <mx:GridRow width="100%" height="100%"> <mx:GridItem width="100%" height="100%"> </mx:GridItem> <mx:GridItem width="100%" height="100%" verticalAlign="middle"> <mx:Button label="Save as ByteArray" click="saveByteHandler(event)" width="100%"/> </mx:GridItem> </mx:GridRow> <mx:GridRow width="100%" height="100%"> <mx:GridItem width="100%" height="100%" colSpan="2"> </mx:GridItem> </mx:GridRow> </mx:Grid> </ns1:LabelledBox> <ns1:LabelledBox id="preview_box" paddingBottom="20" paddingLeft="20" paddingRight="20" paddingTop="20" labelPlacement="left" labelPadding="10" cornerRadius="5" title="Saved Image" clipContent="false" minWidth="300" minHeight="100" direction="horizontal" width="{original_box.width}"> <mx:Grid> <mx:GridRow width="100%" height="100%"> <mx:GridItem width="100%" height="100%" verticalAlign="middle"> <mx:Label text="" id="image_size" /> </mx:GridItem> </mx:GridRow> <mx:GridRow width="100%" height="100%"> </mx:GridRow> </mx:Grid> </ns1:LabelledBox> </mx:VBox> </mx:Application>
In the swf file there are 2 methods for sending data to PHP: saveJpegHandler and saveByteHandler.
3.1 saveJpegHandler
The first one get the original image Bitmapdata encodes it using the JPEGEncoder class (and passing as argument the target jpeg optimization value):
var bmpdata:BitmapData = Bitmap(original_image.content).bitmapData; var ba:ByteArray; encoder = new JPGEncoder(jpeg_quality.value); ba = encoder.encode( bmpdata );The server will return a string containing the path of the saved image, so we will just load the image using an SWFLoader:
swf_loader.load(path + "?rand=" + new Date().getTime());Add the "?rand" parameter just to disable the browser cache...
3.2 saveByteHandler
This second method instead just send the bytearray as it is to amfphp and it expects as result a bytearray object too:
// get the original bitmapdata var bmpdata:BitmapData = Bitmap(original_image.content).bitmapData; // transform the bitmapdata into a bytearray var arr:ByteArray = Bitmap(original_image.content).bitmapData.getPixels(new Rectangle(0,0,bmpdata.width, bmpdata.height));Transform the image Bitmapdata into a Bytearray object using the Bitmapdata getPixels method and send it to the server.
The AMFPHP method will return a new bytearray object, so we can use it to create a bitmapdata using the Bitmpadata setPixels method:
// server returns a bytearray var ba:ByteArray = event.result as ByteArray; // create a new bitmapdata to store into the resulting bytearray pixels var data:BitmapData = new BitmapData(original_image.width, original_image.height, false, 0); var bmp:Bitmap = new Bitmap(data); // draw the bytearray into just created bitmapdata data.setPixels(data.rect, ba); // then add the bitmap to a new UIComponent ui_loader.addChild(new Bitmap(data)); ui_loader.width = data.width; ui_loader.height = data.height;
4. Download files
Download files used in this tutorial
