compress images at client side

1. Allow user to browse for image on their local system
2. Convert file reference into BitmapData
3. Scale BitmapData to fit inside a MAX resolution
4. Compress and encode the BitmapData into a ByteArray
5. Send ByteArray to server-side script to create and save the image file

After finding several articles covering pieces of these steps, I was able to stitch together the code to achieve the above goal. To use my code examples, you will need to use Flex 3 targeted for Flash Player 10 and Zend AMF to send the image data to your server.

<?xml version=“1.0″ encoding=“utf-8″?>
<mx:Application xmlns:mx=“http://www.adobe.com/2006/mxml” layout=“absolute”>
        <mx:Script>
                <![CDATA[
               
                        import mx.graphics.codec.JPEGEncoder;
               
                        private var _fileRef:FileReference;
                        private var _netConnection:NetConnection;
                        private var _imageByteArray:ByteArray;
                       
                        private static const MAX_SIZE:Number = 300;
                       
                        private function getFile():void{
                                _fileRef = new FileReference();
                                _fileRef.addEventListener(Event.SELECT,onFileSelect);
                                _fileRef.browse();
                        }
                        private function onFileSelect(e:Event):void{
                                _fileRef.addEventListener(Event.COMPLETE,onFileLoad);
                                _fileRef.load();
                        }
                        private function onFileLoad(e:Event):void{
                                var loader:Loader = new Loader();
                                loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
                                loader.loadBytes (_fileRef.data);
                        }
                        private function onImageLoaded(e:Event):void{
                                var loadedBitmap:Bitmap = Bitmap(e.target.content);
                                var scale:Number = getScale(loadedBitmap);
                                var bmpData:BitmapData = new BitmapData(loadedBitmap.width * scale, loadedBitmap.height * scale,false);
                                var matrix:Matrix = new Matrix();
                                matrix.scale(scale,scale);
                                bmpData.draw(loadedBitmap,matrix)
                                var jpg:JPEGEncoder = new JPEGEncoder(60);
                                _imageByteArray = jpg.encode(bmpData);
                                uploadImage();

                        }
                        private function getScale(img:Bitmap):Number{
                                var scale:Number;
                                if(img.width > MAX_SIZE){
                                        scale = MAX_SIZE / img.width;
                                }
                                else if(img.height > MAX_SIZE){
                                        scale = MAX_SIZE / img.height;
                                }
                                else{
                                        scale = 1;
                                }
                                return scale;
                        }
                        private function uploadImage():void{
                                _netConnection = new NetConnection();
                                _netConnection.connect(‘http://localhost:8888/_PHP/classes/’);
                                var res:Responder = new Responder(onDataResult, onDataError);
                                _netConnection.call(“KingHippo.saveImage”,res,_imageByteArray);
                        }
                        public function onDataResult(obj:Object):void{
                                trace(obj);/////FILE SAVED
                        }
                        public function onDataError(obj:Object):void{
                                trace(‘error’);///////OOPS
                        }
                ]]>
        </mx:Script>

        <mx:Button label=“browse” click=“getFile()” />

</mx:Application>

That pretty much wraps up the Flex code. I’ll explain the code referring to our original goal list.

1. Allow user to browse for image
Here we have a simple Button that calls a function that will instantiate a file reference object and use its browse() method to prompt the user with their local file browser.

2. Convert file reference into BitmapData
Upon file select, we will need to get this file loaded in to grab its BitmapData. This is where Flash Player 10 comes in. We now have some cool FileReference additions to play with and can now load in the file selected. First we call the load() method. When COMPLETE, we have access to the data of that file which means we can use a Loader to load the bytes of the data using the loadBytes() method from our Loader.

3. Scale BitmapData to fit inside a MAX resolution
OK, so now we have our image data and its time to do some BitmapData trickery. First we need to set the incoming data to a Bitmap object. Next we determine how much we need to scale down the image by using our MAX_SIZE variable. Here I’m using 300 so the width or height will not exceed that number. Once I determine the scale value (using the getScale function) , I can now create and manipulate my Bitmap Data. I create a new BitmapData object and set it to the appropriate size using my scale value against the image’s original size. Now I need to draw from the loaded image. It’s not enough to just draw it b/c it will just grab that rect from the original image data, essentially cropping it. We need to use Matrix to set the scale of the original data within our draw() method.
Now we have our image data and appropriate resolution.

4. Compress and encode BitmapData into a ByteArray
Next, using Flex’s JPEGEncoder, we can compress the data and encode it to a ByteArray. Simply create a new JPEGEncoder object and pass a quality value to its constructor. The values are 1 – 100. Here I’m using 60. Then we call the JPEGEncoder’s encode() method which will then give us our long-awaited ByteArray. Now we can pass it on to the server.

5. Send ByteArray to server-side script to create image file
Lastly, we need to send off the image data to the server. Here I’m using Zend AMF and sending the ByteArray to a PHP class.

Now we are done on the Flex end. The last thing we need to do is create the image file from the data sent to the server and save it.
PHP code below..

<?php
class KingHippo{       
       
        public function __construct(){
                //////construct
        }
        public function saveImage($obj){
                $fp = fopen(‘myNewImage.jpg’, ‘wb’);
                fwrite( $fp, implode(”,$obj));
                fclose( $fp );
                return “FILE SAVED”;
        }
}

<?

你可能感兴趣的:(PHP,Flex,Flash,Zend,FP)