Menu:

Sponsor

Discover Master of Alchemy, our first iPad/iPhone and iPod touch game!

Follow Me

 

Forum's topics

Latest Files

Archives

Top Rated

Categories

Photo Gallery


Send and Receive ByteArray to AMFPHP

3. Flex

Ok, first of all let's see at the final swf file (right click to display the source):

This text is replaced by the Flash movie.

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