Friday, August 6, 2010

Working with files in Actionscript 3: Part 5

In this AS3 tutorial we will learn how to let the user upload an image from his computer into the flash.

This is how the final product is going to look like:



Let's get started!

Firstly, we need to set everything on the stage. You will need: an empty movieclip, a button and an UILoader. Create a button and place it on the stage - this will be the Browse button. Give it an instance name of load_bt. Now create an empty movieclip and put it on the stage (under the button), give it an instance name of holder. This will be the MC that the loaded image will be loaded into (using addChild method). Now all we need is an UI Loader, which can be found in the components menu. Open it up and just drag the UI Loader component into your library (not the stage).


Now the plan of our work:
- import container class for uiloader to work (note, if you are writing this in a separate .as file then you'll need to import other stuff too)
- set up our FileReference object, attach it to our button, give it an image filter
- set up listener for user selecting file in his browse window
- create a function loadExternalImage that will turn the data retrieved from the image file into a bitmap, ready to use in Flash
- attach loadExternalImage to our select handler

How does loadExternalImage function work? First it waits for the FileReference object to fully load, then clears our loaderUI (in case there already is something in it) and turns it into an image by loading bytes from our FileReference object. Final step - attach the image to our holder movieclip.

Here is the full, commented code.

// import container (for uiloader)
import fl.containers.*;
// give listener to the upload button
load_bt.addEventListener(MouseEvent.CLICK, selectFiles);
// opening browse window with image formats
function selectFiles(event:MouseEvent){
 fileRef.browse([new FileFilter("Images", "*.jpg;*.jpeg;*.gif;*.png")]);
}
// create a file reference object
var fileRef:FileReference = new FileReference();
// add listener for user selecting a file in the browse window
fileRef.addEventListener(Event.SELECT, selectHandler);
// call the loadexternalimage function on our file reference object
// when it is selected
function selectHandler(event:Event):void{
 loadExternalImage(fileRef)
}
// create an ui loader to hold image data
var loaderUI:UILoader = new UILoader();
// loadexternalimage function, which turns data into image
function loadExternalImage(userFilesReference:FileReference){
 // add listener for loading completion
 userFilesReference.addEventListener(Event.COMPLETE, onComplete);
 // load the file reference object
 userFilesReference.load();
 // what happens when loading completes:
 function onComplete(event:Event){
  // clean up
  loaderUI.unload();
  // load all image data to loaderUI
  loaderUI.loadBytes(userFilesReference.data);
  // add this image to holder mc on stage
  holder.addChild(loaderUI);
 }
}

Thanks for reading!

Related:

Working with files in Actionscript 3: Part 1
Working with files in Actionscript 3: Part 2
Working with files in Actionscript 3: Part 3
Working with files in Actionscript 3: Part 4

4 comments:

Anonymous said...

Hi, this is very useful information however the images are not resizing and its supoussed that the UILoader scales its content. is necessary that I resize the image with other method or is there a way to make the content scale on loadBytes?.

Thanks a lot.

Kirill Poletaev said...

If you want to resize, you should use Loader instead of UILoader and listen for the moment, when the whole picture is done loading (through loadBytes();). Here's the full code you should use in this situation:

// import container (for uiloader)
import fl.containers.*;
// give listener to the upload button
load_bt.addEventListener(MouseEvent.CLICK, selectFiles);
// opening browse window with image formats
function selectFiles(event:MouseEvent){
fileRef.browse([new FileFilter("Images", "*.jpg;*.jpeg;*.gif;*.png")]);
}
// create a file reference object
var fileRef:FileReference = new FileReference();
// add listener for user selecting a file in the browse window
fileRef.addEventListener(Event.SELECT, selectHandler);
// call the loadexternalimage function on our file reference object
// when it is selected
function selectHandler(event:Event):void{
loadExternalImage(fileRef)
}
// create an ui loader to hold image data
var myLoader:Loader = new Loader();
// loadexternalimage function, which turns data into image
function loadExternalImage(userFilesReference:FileReference){
// add listener for loading completion
userFilesReference.addEventListener(Event.COMPLETE, onComplete);
// load the file reference object
userFilesReference.load();
// what happens when loading completes:
function onComplete(event:Event){
// clean up
myLoader.unload();
// load all image data to myLoader
myLoader.loadBytes(userFilesReference.data);
// add this image to holder mc on stage
}
}

myLoader.contentLoaderInfo.addEventListener(Event.INIT, loadComplete)

function loadComplete(event:Event):void {
holder.addChildAt(myLoader, 0);
myLoader.width=500
myLoader.height=260
}

Anonymous said...

hi need a little help how can i add more holder/containers for several images to load thank you!

Kirill Poletaev said...

You could turn the code into a reusable class and use it for each container. You'll need some knowledge of OOP for that, you can read my tutorials to learn about it.

A dirty way to do this would be to copy and paste the code for each container, changing the variables' and holders' names every time.

Post a Comment