11 Replies Latest reply on Apr 9, 2010 6:45 PM by David_F57

    Resizing selected image and making it a File

    DaanLy Level 1

      Hey,

       

      I'm working on a CMS but I can figure out this problem.
      Idea:
      Client chooses image on his/her HDD -> Code makes a resized version of the selected File.

      Code:

      ---- My File Class ----

      private var _localImage:File;

       

      ---- Client clicks on the browse button ------
                private function onBrowseBtnClick( event:MouseEvent ):void
              {
                  var fileFilter:FileFilter = new FileFilter( "Images", "*.jpg;*.gif;*.png" );
                 
                  try
                  {
                      _localImage.browse( [fileFilter] );
                      _localImage.addEventListener( Event.SELECT, onFileBrowseSelect );
                  }
                  catch( error:Error )
                  {
                      trace("Failed:", error.message);
                  }
              }
             
      ---- Client selects image ------
              private function onFileBrowseSelect( event:Event ):void
              {
                  imageInput.text = _localImage.nativePath;
                  imgLoader.load( "file:///" + _localImage.nativePath );
                  saveBtn.enabled = revertBtn.enabled = true;
              }

       

      At this stage the client can upload images but always on a 1x1 scale.

       

      Is there a way to manipulate the File so that it has a fixed width of 500?

      I got all the uploading codes etc. just need to find a way to alter the selected image (give the right height and width), make it a File and upload it.

      I tried BitmapArrays and BitmapDatas but I cant figure it out.

      Any ideas?

        • 1. Re: Resizing selected image and making it a File
          David_F57 Level 5

          Hi,

           

          If you create a an action script file called ImageResize.as and insert this code, it will take care of resizing.

           

          Using ImageResize

           

          var newBitmap:Bitmap = ImageResize.rescale(myImage, 500);  <--- takes an existing image and scales it to a width of 500

          var ba: ByteArray = PNGEncoder.encode(newBitmap.bitmapData); <-- take the result and convert it to a png bytearray

           

           

          now you can upload the bytearray to a file - I used the pngencoder here but you can also use the jpgencoder if you prefer.

           

          David.

           

          package

          {

               import flash.display.Bitmap;

               import flash.display.BitmapData;

               import flash.display.DisplayObject;

               import flash.geom.Matrix;

               

               public class ImageResize

               {

                    public static function rescale(content:DisplayObject, width:int):Bitmap{

                          var ar:Number=content.width/content.height;

                          var cw:Number;

                          var ch:Number;

                          if(ar>1){

                            cw = width;

                            ch = width/ar;                                     

                          }else{

                            cw = width;

                            ch = width*ar;                

                          }

                          var scale:Number=width/content.width;

                          return new Bitmap(getScaledBitmapData(content,scale));

                    }

                    

                    private static function getScaledBitmapData(target:DisplayObject,scale:Number):BitmapData{

                         var bd : BitmapData = new BitmapData(target.width*scale,target.height*scale);

                         var mt:Matrix=new Matrix();

                         mt.scale(scale,scale);

                         bd.draw(target,mt);

                         return bd;

                    }

               }

          }

          1 person found this helpful
          • 2. Re: Resizing selected image and making it a File
            David_F57 Level 5

            I hate how this forum corrupts code, maybe this time

             

            package

            {

            import flash.display.Bitmap;

            import flash.display.BitmapData;

            import flash.display.DisplayObject;

            import flash.geom.Matrix;

             

            public class ImageResize

            {

            public static function rescale(content:DisplayObject, width:int):Bitmap{

            var ar:Number=content.width/content.height;

            var cw:Number;

            var ch:Number;

            if(ar>1){

                    cw = width;

                    ch = width/ar;

            }else{

                    cw = width;

                    ch = width*ar;

            }

            var scale:Number=width/content.width;

            return new Bitmap(getScaledBitmapData(content,scale));

            }

             

            private static function getScaledBitmapData(target:DisplayObject,scale:Number):BitmapData{

            var bd : BitmapData = new BitmapData(target.width*scale,target.height*scale);

            var mt:Matrix=new Matrix();

            mt.scale(scale,scale);

            bd.draw(target,mt);

            return bd;

            }

            }

            }

            1 person found this helpful
            • 3. Re: Resizing selected image and making it a File
              DaanLy Level 1

              Thx David! Really

               

              1 more question tho...
              Your code seems to work and I made a ByteArray via PNGEncoder. But how do I overwrite the "_localImage" File var with that new ByteArray, because the _localImage is the file being uploaded.

              Hope you get what I'm saying here xD

               

              (Its the first time I'm working with image manipulation so all the bytearray and bitmap thingies are new for me so sorry )

              • 4. Re: Resizing selected image and making it a File
                David_F57 Level 5

                Hi,

                 

                I think this is what you want - it will write the png file to the local documents folder

                 

                var file : File = File.documentsDirectory.resolvePath("image.png");

                var stream: FileStream = new FileStream();

                stream.open(file,FileMode.WRITE);

                stream.writeBytes(ba,0,ba.length);

                stream.close();

                 

                David.

                • 5. Re: Resizing selected image and making it a File
                  DaanLy Level 1

                  There is no way of doing this without writing a file to the local documents folder?

                   

                  The image file is an attribute of class, lets say "Sneaker".
                  It has a bunch of attributes like size, brand, ...
                  The client can insert multiple sneakers via the CMS and then upload the sneaker. When they do that, the application generates an XML file with the data and upload the image files to the server.

                  So i wanna do this without writing anything local...

                   

                  Oh and when i try it with the code you gave me it generates a white image.png...

                  • 6. Re: Resizing selected image and making it a File
                    DaanLy Level 1

                    The size of the image is correct tho...

                    • 7. Re: Resizing selected image and making it a File
                      David_F57 Level 5

                      Hi,

                       

                      I'll check that issue with image I wrote that code about 2 years ago so I suppose I shoud have tested it first

                       

                      When you upload the image can you do it as binary ?.

                       

                      I thought you had the upload side sorted for instance how are you currently uploading the full size image...

                       

                      David

                      • 8. Re: Resizing selected image and making it a File
                        DaanLy Level 1

                        When they click the upload button:
                        private function uploadChanges():void
                            {
                                if( !_uploading )
                                {
                                    _uploading = true;
                                    this.enabled = false;
                                    CursorManager.setBusyCursor();
                                    _xmlDataService.updateXMLData( _listDataService.serialize( _listData ), _homeDataService.serialize(_homeDataArray) );
                                }
                            }

                         

                        It goes to the xmlDataService:

                         

                        public function updateXMLData( homeXML:XML, listXML:XML ):void
                                {
                                    _xmlData = listXML;
                                    _xmlHomeData = homeXML;
                                    save()
                                }

                         

                        After that:

                        private function save():void
                                {
                                    var output:String = UTF_ENCODING + "\n" + "<content>" + "\n" + _xmlHomeData.toXMLString()
                                    + _xmlData.toXMLString()+ "\n" + "</content>";
                                    output = output.replace( /\n/g, File.lineEnding );
                                   
                                    _fileStream = new FileStream();
                                    _fileStream.openAsync( SettingsModel.getInstance().localDataFile, FileMode.WRITE );
                                    _fileStream.addEventListener( Event.CLOSE, onFileWriteComplete );
                                    _fileStream.writeUTFBytes( output );
                                    _fileStream.close();
                                }

                        Now the XML is updated
                        Next step:

                        private function onFileWriteComplete( event:Event ):void
                                {
                                    dispatchEvent( new Event( Event.COMPLETE ) );
                                }

                        Calls:

                        private function onXMLDataLoaded( event:Event ):void
                            {
                                if( _uploading )
                                {
                                    _uploadService = null;
                                    _uploadService = new UploadService();
                                    _uploadService.addEventListener( Event.COMPLETE, onUploadComplete );
                                    _uploadService.addFile( _settings.localDataFile );
                                    _uploadService.addFiles( _listDataService.getLocalFiles( _listData ),_homeDataService.getLocalFiles(_homeDataArray) );
                                    _uploadService.startUpload();
                                }
                                else
                                {
                                    unselect();
                                    _listData = _listDataService.deserialize( _xmlDataService.xmlData );
                                    _homeDataArray = _homeDataService.deserialize( _xmlDataService.xmlData );
                                    homeEditor.update(HomeData(_homeDataArray[0].data));
                                    CursorManager.removeBusyCursor();
                                    this.enabled = true;
                                }
                            }

                         

                        In the upload service:


                        public function startUpload():void
                                {
                                    if( !_uploading )
                                    {
                                        _uploading = true;
                                        nextFile();
                                    }
                                }

                         

                        private function nextFile():void
                                {
                                    _currentIndex++;
                                   
                                    if( _currentIndex != _filesToUpload.length )
                                    {
                                        var fileToUpload:File = _filesToUpload[_currentIndex];
                                        fileToUpload.addEventListener( IOErrorEvent.IO_ERROR, onUploadError );
                                        fileToUpload.addEventListener( DataEvent.UPLOAD_COMPLETE_DATA, onUploadCompleteData );
                                       
                                        var uploadReqest:URLRequest = new URLRequest();
                                        uploadReqest.method = "POST";
                                        uploadReqest.url = ( _currentIndex == 0 ) ? SettingsModel.getInstance().gatewayURL + "?action=uploadData" : uploadReqest.url = SettingsModel.getInstance().gatewayURL + "?action=uploadAsset";

                         

                                        try
                                        {
                                            fileToUpload.upload( uploadReqest );
                                        }
                                        catch( error:Error )
                                        {
                                            dispatchEvent( new ErrorEvent( ErrorEvent.ERROR ) );
                                        }
                                    }
                                    else
                                    {
                                        _uploading = false;
                                        dispatchEvent( new Event( Event.COMPLETE ) );
                                    }
                                }

                         


                        The gateway.php:

                        switch( $_GET['action'] )
                        {

                         

                            case 'validate':
                                handleValidate();
                                break;
                           
                            case 'uploadAsset':
                                handleUploadAsset();
                                break;
                               
                            case 'uploadData':
                                handleUploadData();
                                break;      

                         

                        }

                         

                        function handleValidate()
                        {
                            echo 'success=1&xmlDataURL='.$GLOBALS['xmlDataURL'].'&assetsFolderURL='.$GLOBALS
                                ['assetsFolderURL'];
                        }

                         

                        function handleUploadData()
                        {
                            echo "\nReceiving upload...\n";
                            echo "Filename: " . $_FILES['Filedata']['name']."\n";
                            echo "File Size: " . $_FILES['Filedata']['size']."\n";
                            move_uploaded_file($_FILES['Filedata']['tmp_name'], $GLOBALS['xmlDataPath']);
                            echo "File moved to: ".$GLOBALS['xmlDataPath']."\n";
                        }

                         

                        function handleUploadAsset()
                        {
                            echo "\nReceiving upload...\n";
                            echo "Filename: " . $_FILES['Filedata']['name']."\n";
                            echo "File Size: " .$_FILES['Filedata']['size']."\n";
                            move_uploaded_file($_FILES['Filedata']['tmp_name'], $GLOBALS
                                ['assetsFolderPath'] .$_FILES['Filedata']['name']);
                            echo "File moved to: ".$GLOBALS['assetsFolderPath'].$_FILES
                                ['Filedata']['name']."\n";
                        }

                         

                         

                         

                        Thats about it I think...

                        • 9. Re: Resizing selected image and making it a File
                          DaanLy Level 1

                          As you can see... the code gathers all the localfiles from the different dataServices (= the images) and puts them in an Array and then uploads them 1 by 1...

                           

                          So all I should do is, replace the original File (=image) by the resized one (without writing it away localy) and my problem is solved...

                          • 10. Re: Resizing selected image and making it a File
                            DaanLy Level 1

                            Update!

                             

                            The resizing works, aswell as saving the image in the local documents folder. There was something wrong with the call of the file write thingy, but it works now...
                            Only thing left is making the resized image the file that is being uploaded.

                            And if that doesnt work, maybe I should just save the images loacaly and after the upload delete them... option?

                            • 11. Re: Resizing selected image and making it a File
                              David_F57 Level 5

                              Hi,

                               

                              Sorry that I haven't had the time to have a good look at this, the encoding to png  issue was due to the pngencoder, as I said it was old code and since then PNGEncoder has become a flex class which is inititated slightly differently to the way my code which used a 3rd party encoder class.

                               

                              I think it would be quicker to right the file to a tmp folder and use your existing process rather than modify the existing process(that obviously works) to handle the png byte array directly.

                               

                              I normally use amfphp backendroutines to upload and store the bytearrray directly in a mysql database.

                               

                              If upload size is an issue jpg encoding is an option but the jpgencoder is about 4 times slower than png encoder.

                               

                              David.