9 Replies Latest reply on Aug 1, 2009 11:37 AM by hamochi

    FileReference problem

    Flex-Issac Level 1
      Hi All,

      My program need to select jpg or text file in client side, then update to server side using socket. But FileReference class only allow upload(URL). How can I selected local file in FileReferenceList class and transform the file to be byteArray?

      Thanks
        • 1. Re: FileReference problem
          Starlover_jacob

          Hi, i have the same problem.

           

          I also want to use filereference to get bytearry or bitmapdata, cause i want to resize my image first before i send it to the server.

           

          possible solution is use upload to get it to the server, than download it again using a loader.. get the bytearray etc.

          resize the image and then upload it again..

          A bit of taking the long way home don't you think?

           

          So please also from me, some help here.

           

          Greets, J.

          • 2. Re: FileReference problem
            hamochi

            Hi guys, the data property of a filereference instance is will return a byteArray. Something like this:

             

            <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">


            <mx:Script>

                 <![CDATA[

                      private var myRef:FileReference = new FileReference();;

                    

                       private function open():void

                      {

                           myRef.browse();

                           myRef.addEventListener(Event.SELECT,load);

                      }

             

             

                      private function load(event:Event):void

                      {

                           myRef.addEventListener(Event.COMPLETE,done);

                           myRef.load();

             

                      }

             

             

                      private function done(event:Event):void

                      {

                           myImage.source = myRef.data; // this is a byteArray

                      }

             


                      ]]>

            </mx:Script>

            <mx:Button label="open" click="open()"  x="137" y="172"/>

            <mx:Image id="myImage"  x="137" y="212"/>

             

             

            </mx:Application>

             

            Jacob, i'm trying to the exact same thing, i'm working on an app where you can resize and crop pictures before uploading them. So far i'm loading all the selected files as byteArrays, in an array. The idea is to load all files in an array, convert the file you want to resize, crop to bitmapdata and back to byteArray again when your finished with it, and store it in the original array again. Then when you're done with your changes you just upload that array. The downside with my method is that it uses a lot of memory. But i'm facing some difficulties with converting my bitmapdata back to a bytearray again. I'm going to start a new thread on that subject soon =)

            • 3. Re: FileReference problem
              Starlover_jacob Level 1

              Hi,

              I figured out that u need to use flash player 10 in your build.

               

              here a link to set up your flexbuilder to use flash player 10 related classes

              http://www.communitymx.com/content/article.cfm?page=1&cid=105CF

               

              then you can use the filereference.load to get a bytearray

               

              var imagesFilter:FileFilter =
              new FileFilter("Foto (*.jpg, *.gif, *.png)", "*.jpg;*.gif;*.png");
              imageFile = new FileReference();
              imageFile.addEventListener(Event.SELECT, onFileSelected);
              imageFile.browse([imagesFilter]);
              
              private function onFileSelected(event:Event):void
              {
                   imageFile.addEventListener(Event.COMPLETE, imageSelected);
                   imageFile.load();
              }
              private function imageSelected(event:Event):void
              {
                   var fileReference:FileReference=event.target as FileReference;
                   var data:ByteArray=fileReference["data"];       
                     
                   var loader:Loader = new Loader();
                    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onDataLoadComplete);
                    loader.loadBytes(data);               
              }
              private function onDataLoadComplete(e:Event):void 
              {
                   var bitmapData:BitmapData = e.target.content.bitmapData;
                   //resize the original image into a full and a thumb
                   var thumb:BitmapData=resizeimage(bitmapData,120,120);
                   var thumbdata:ByteArray = encodeToJpg(thumb);     // convert bitmapdata to a jpg bytearry
              }
              
              
              
              
              // function to resize images
                   private function resizeimage(image:BitmapData,maxx:Number,maxy:Number):BitmapData
                   {
                        var bmp:BitmapData =image;
                        var true_width:Number = bmp.width;
                        var true_height:Number = bmp.height;
                        var resize:Boolean=false;
                        
                        if (true_width>maxx) resize=true;
                        if (true_height>maxy) resize=true;
                        if (resize==true)
                        {
                             var width:Number=maxx;
                             var height:Number = (width / true_width) * true_height;
                             true_width=width;
                             true_height=height;
                        
                             if (true_height>maxy)
                             {
                                  height=maxy;
                                  width = (height/true_height)*true_width;     
                             } 
                             else 
                             {
                                  width=true_width;
                                  height=true_height;
                             }
                        } 
                        else 
                        {
                             width=true_width;
                             height=true_height;
                        }
                             //new calculated width and heigt relative to the given maxx and maxy.      
                        width=Math.ceil(width);
                        height=Math.ceil(height);                    
              
                   
                             //create a new image object with the calculated widht and height for the smaller image
                        var mysmallimage:Image=new Image();
                        mysmallimage.width=width;
                        mysmallimage.height=height;
              
                             //new matrix for smaller image
                        var m:Matrix = new Matrix() ;
                             //scale the matrix to the correct sizes.
                        m.scale( mysmallimage.width / bmp.width, mysmallimage.height / bmp.height ) ;
                             //draw the image into the image object
                        mysmallimage.graphics.beginBitmapFill( bmp, m, false, true ) ;
                        mysmallimage.graphics.drawRect( 0, 0, mysmallimage.width, mysmallimage.height ) ;
                        mysmallimage.graphics.endFill();
                        
                             //put the smaller image into bitmapdata so it can be returned.
                        var littlebitmapdata:BitmapData=new BitmapData(mysmallimage.width,mysmallimage.height,false,0xFFFFFFFF );
                        littlebitmapdata.draw(mysmallimage);
                        
                             // set the temporary small image to null so the GC can remove it from the memmory.
                        mysmallimage=null;
                        bmp=null;
                                                                     
                             //returning the small image.     
                        return littlebitmapdata;               
                   }
              
                   // encoder to jpg
                   private function encodeToJpg(bmd:BitmapData):ByteArray 
                   {
                       var jpg:JPEGEncoder= new JPEGEncoder();
                       return jpg.encode(bmd);
                   }
              

               

              Hamochi;

              As you can see i resize my loaded image. (as a bitmapdata)

              then i use a jpegencoder to convert it to a jpg.

              As a result i get a bytearray again.

               

              Hopefully this helps you  a bit.

               

              Greets, Jacob

              • 4. Re: FileReference problem
                hamochi Level 1

                Hi, thanks for the tip, using the JPEGencoder was a good idea. Now i've run into a new problem. I've decided to use a FileReferenceList to load many files at the same time, convert them to bitmap and store them to in a array. And later on i can play with the bitmaps and covert them to ByteArray when i'm ready to upload them.

                 

                I load them successfully into a array and i can view them, but only once :S it's like the data disappears from the memory once i've viewed it. Here is my code: (listFiles is a List, myPic an image and addFiles() is my initial function, i'm not adding any codes for the visual stuff here)

                 

                private var ref:FileReference = new FileReference;
                
                private var reflist:FileReferenceList = new FileReferenceList;
                
                private var loader:Loader;
                
                                    
                
                private var picArr:Array = new Array;
                
                                    
                
                private function addFiles():void
                
                {
                
                     reflist.addEventListener(Event.SELECT, select);
                
                     reflist.browse();
                
                }
                
                          
                
                private function select(event:Event):void
                
                {
                
                     for(var i:uint=0;i<reflist.fileList.length;i++)
                
                        {
                
                          reflist.fileList[i].addEventListener(Event.COMPLETE,open);
                
                          reflist.fileList[i].load();
                
                     }
                
                }
                
                                    
                
                private function open(event:Event):void
                
                {
                
                     var tempFileRef:FileReference = event.target as FileReference;
                
                     loader = new Loader;
                
                     loader.name = event.target.name;
                
                     loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadArray);
                
                     loader.loadBytes(tempFileRef.data);
                
                }
                
                                    
                
                private function loadArray(event:Event):void
                
                {
                
                          picArr.push({label:event.target.content.parent.name, data:event.target.content});
                
                          listFiles.dataProvider = picArr;
                
                }
                
                private function getSelectedFile():void
                
                {
                
                
                myPic.source = picArr[listFiles.selectedIndex].data;
                
                
                }
                
                

                The function getSelectedFile fires up when i click in my list. To be clear:

                I can select my pictures, and they load into an array, and the files load into the list, when i click the list, i access the array and get the bitmap from there. The first time i click in the list , i can see the image, the second time i click in the list, the image disappears. When i run the profile, i see a memory drop every time i click in the list :S

                 

                thanks.

                • 5. Re: FileReference problem
                  Starlover_jacob Level 1

                  Hi,

                   

                  Frist; what i always do is i seperate the problem from the big picture (big project)

                  So i have no interference of other stuff inside my big project.

                  Just make a little project with only the selection of files, the list and an img file to show the img from the list.

                   

                  Now your problem..

                  When you debug and watch the picarr, there are several objects in it? not only the first?

                  Before you push the data of the selected image to the image object on your screen, i should empty it.

                  mypic.source=null;

                  mypic.source=picArr[listfiles.selectedindex].data (also put a watch on [listfiles.selectedindex].data and check if its not empty)

                   

                  perhaps you can put all the code of your little project here, so i can run some test for myselve.

                   

                  Greets, Jacob

                  • 6. Re: FileReference problem
                    hamochi Level 1

                    Hi Jacob, I also try to isolate my problem into a separate small project to narrow down possible mess ups . In this small project i'm loading selected files into new loaders as ByteArrays and from the loaders i pull of the bitmap and store them into an array. I put a watch on my array (picArray) and it drops the bitmapdata of the objects its holding as soon as i have used them as my image source :S. Here is my code

                     

                    <?xml version="1.0" encoding="utf-8"?>
                    
                    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
                              <mx:Script>
                    
                                   <![CDATA[
                    
                                        private var ref:FileReference = new FileReference;
                    
                                        private var reflist:FileReferenceList = new FileReferenceList;
                    
                                        private var loader:Loader;
                    
                                        private var u:uint = 0;
                    
                                        private var picArr:Array = new Array;
                    
                                        
                    
                                        
                    
                                        private function addFiles():void
                    
                                        {
                    
                                             reflist.addEventListener(Event.SELECT, select);
                    
                                             reflist.browse();
                    
                                        }
                    
                              
                    
                                        private function select(event:Event):void
                    
                                        {
                    
                                             for(var i:uint=0;i<reflist.fileList.length;i++)
                    
                                             {
                    
                                                  reflist.fileList[i].addEventListener(Event.COMPLETE,open);
                    
                                                  reflist.fileList[i].load();
                    
                                             }
                    
                                        }
                    
                                        
                    
                                        private function open(event:Event):void
                    
                                        {
                    
                                             var tempFileRef:FileReference = event.target as FileReference;
                    
                                             loader = new Loader;
                    
                                             loader.name = event.target.name;
                    
                                             loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadArray);
                    
                                             loader.loadBytes(tempFileRef.data);
                    
                                        }
                    
                                        
                    
                                        private function loadArray(event:Event):void
                    
                                        
                    
                                        {
                    
                                             var bbb:Bitmap = new Bitmap;
                    
                                             bbb = Bitmap(event.target.content);
                    
                                             
                    
                                             picArr.push({label:event.target.content.parent.name, sak:bbb});
                    
                                             listFiles.dataProvider = picArr;
                    
                                        }
                    
                                        private function getSelectedFile():void
                    
                                        {
                    
                                             myPic.source = null;
                    
                                             myPic.source = picArr[listFiles.selectedIndex].sak;
                    
                                        }
                    
                                   ]]>
                    
                              </mx:Script>
                    
                    
                              <mx:HDividedBox x="10" y="10" width="1106" height="557"  horizontalScrollPolicy="off" verticalScrollPolicy="off">
                    
                                   <mx:Canvas top="10" bottom="10" left="10" right="10">
                    
                              <mx:Panel width="300" height="528" layout="absolute" horizontalCenter="0" verticalCenter="1" id="panUpload" title="Select files for upload">
                    
                                   <mx:VBox left="10" bottom="10" top="10" right="10">
                    
                                        <mx:List width="100%" id="listFiles" height="100%" allowMultipleSelection="true" click="getSelectedFile()"/>
                    
                                        <mx:HBox width="100%" horizontalAlign="center">
                    
                                             <mx:Button label="Add file(s).." id="btnAdd" click="addFiles()" />
                    
                                             <mx:Button label="Remove file(s)" id="btnRemove"/>
                    
                                        </mx:HBox>
                    
                                   </mx:VBox>
                    
                                   
                    
                                   <mx:ControlBar>
                    
                                        <mx:Grid>
                    
                                             <mx:GridRow>
                    
                                                  <mx:GridItem>
                    
                                                       <mx:Button label="Upload" id="btnUpload"  enabled="false" width="126"/>     
                    
                                                  </mx:GridItem>
                    
                                                  <mx:GridItem>
                    
                                                       <mx:Button label="Save"  width="137" height="21"/>
                    
                                                  </mx:GridItem>
                    
                                             </mx:GridRow>
                    
                                             <mx:GridRow>
                    
                                                  <mx:GridItem>
                    
                                                       <mx:Label text="Guides" width="125" textAlign="center" id="aa"/>
                    
                                                  </mx:GridItem>
                    
                                                  <mx:GridItem>
                    
                                                       <mx:Label text="Size" width="134" textAlign="center"/>
                    
                                                  </mx:GridItem>
                    
                                             </mx:GridRow>
                    
                                             <mx:GridRow>
                    
                                                  <mx:GridItem>
                    
                                                       <mx:ComboBox x="54" y="114" width="127"></mx:ComboBox>
                    
                                                  </mx:GridItem>
                    
                                                  <mx:GridItem>
                    
                                                  
                    
                                                           <mx:HSlider id="hSlider" minimum="0" maximum="100" value="100" 
                    
                                                                   dataTipPlacement="top" 
                    
                                                                 tickColor="black" 
                    
                                                                 snapInterval="1" tickInterval="10" 
                    
                                                                 labels="['0%','100%']" 
                    
                                                                 allowTrackClick="true" 
                    
                                                                 liveDragging="true"/>
                    
                                                  </mx:GridItem>
                    
                                             </mx:GridRow>
                    
                                        </mx:Grid>
                    
                                   </mx:ControlBar>
                    
                    
                              </mx:Panel>
                    
                         </mx:Canvas>
                    
                    
                         <mx:Panel width="300" height="529" layout="absolute" horizontalCenter="0" verticalCenter="1"  title="Current Image"  id="panelen">
                    
                              <mx:Image id="myPic" scaleContent="false"/>
                    
                         </mx:Panel>
                    
                    
                         </mx:HDividedBox>
                    </mx:Application>
                    
                    

                    Sorry to bother you.

                    Thanks /hamochi

                    • 7. Re: FileReference problem
                      hamochi Level 1

                      The code looks funny in my last post.

                       

                      You can find the project here:

                       

                      http://ehsanaslani.com/hamochi/Imp.zip

                       

                      Cheers.

                      • 8. Re: FileReference problem
                        Starlover_jacob Level 1

                        Hi,

                         

                        I solved your problem by removing all children of the panel and create a new image object each time you click an item in the list and used addchild to add the new image to the panel.

                         

                        so what do you need to do:

                        create a public var.

                        public var  myPic:Image;
                        

                        Remove the image item that is fixed on your screen;

                           <mx:Panel width="300" height="529" layout="absolute" horizontalCenter="0" verticalCenter="1"  title="Current Image"  id="panelen"
                                
                            </mx:Panel>
                        

                        And use the following code when you click an item in the list

                        private function getSelectedFile():void
                        {
                             panelen.removeAllChildren();
                             myPic=new Image();
                             myPic.source=picArr[listFiles.selectedIndex].sak;
                             panelen.addChild(myPic);
                        }
                        

                         

                        That solved the weird loading problem.

                        I looked for another solution to load the image, so can't tell you why it didn't work the way you wanted at the first time.

                         

                        Afterall.. a working solution is a solution, so lets do it that way

                         

                        Greets, and succes with your project..

                        Jacob

                        • 9. Re: FileReference problem
                          hamochi Level 1

                          That really worked!!! Your the best!! Seriously thanks a bunch for taking your time to help me.

                           

                          Cheers!!