Feb
01
2011

 

This tutorial will show you how to post photo (MovieClip) into the user’s Facebook photo album. The example is written in Flash CS3, but should be easily ported to Flex and should work in CS4 and 5.

===============

IMPORTANT UPDATE NOTES

Due to changes on Facebook API, change these elements to get this to work on OAUTH2.0:

  • Change response.session to response.authResponse.
  • Change getSession in .js to getAuthResponse.
  • perms is now called scope.

The source link below has the changes already implemented, but the guide still refers to the old names.
===============

For a tutorial on how to set-up the Graph API in AS3, refer to this post:
http://www.permadi.com/blog/2010/12/using-facebook-open-graph-api-in-flash-as3/

 

Step 1

Set-up the application login process using the similar code as in http://www.permadi.com/blog/2010/12/using-facebook-open-graph-api-in-flash-as3/ — shown below if you are already familiar with the API:

[c]
import com.facebook.graph.Facebook;
import com.facebook.graph.data.FacebookSession;
import com.facebook.graph.net.FacebookRequest;

loginButton.addEventListener(MouseEvent.CLICK, onLoginButtonClicked);


// Change the APP ID with your own APP id.
Facebook.init('108257312581900', handleLogin);
		
function onLoginButtonClicked(event:MouseEvent):void
{
	if (Facebook.getSession()==null ||
		Facebook.getSession().uid  == null) 
	{
		// "perms" is now called "scope"
		//Facebook.login(handleLogin, {perms:'publish_stream'});
		Facebook.login(handleLogin, {scope:'publish_stream'});
	} 
	else 
	{
		Facebook.logout(handleLogout);
	}	
}

function handleLogin(response:Object, fail:Object):void 
{
	if (response == null) 
	{
		//resultTxt.text += 'Error login session';
		ExternalInterface.call('redirect');
		return;
	}
	changeToLoginState();
}

function changeToLoginState():void 
{
	//resultTxt.text += 'Logged in';
	loginButton.label = 'Logout';
	loadMyInfo();

}

function loadMyInfo():void
{
	Facebook.api('/me', onMyInfoLoaded);	
}
		
function handleLogout(success:Object):void 
{
	//resultTxt.text += "Logout";
	//loginButton.label = 'Login';
	loginButton.label = 'Login';
	nameTextField.text="Please Login";
}

function onMyInfoLoaded(response:Object,fail:Object):void 
{
	trace("onMyInfoLoaded "+response.name);
	nameTextField.text=response.name;
}
[/c]

Step 2

  • Add a movie clip into the stage, name it mc_photo. This will be our example photo, you can add a bitmap inside this movie clip if you want to.
  • Add a button onto the stage, name it buttonSaveToPhotoAlbum to trigger the saving process.
  • Add the following code to trigger to button to initiate the posting of the photo:
    [c]
    buttonSaveToPhotoAlbum.addEventListener(MouseEvent.CLICK, onSaveToPhotoAlbumClicked);
    [/c]

Step 3

Now here’s the part of how to post a Bitmap into the Facebook Photo Album of the current user. Basically, you can use the me/photos Graph API to do this, passing the image data as multipart/form-data. (More information about me/photos: http://developers.facebook.com/docs/reference/api/photo.) Thankfully, the facebook-actionscript-api will do the multipart/form-data nifty-gritty for you, so you need not to be concerned out it.

As for creating the image data, you can use Flash Bitmap object. And since you can draw MovieClip into Bitmap objects, you can virtually save anything by drawing into a Bitmap object.

In the example below, assume that I have a movie clip named mc_photo on the stage. The code then:

  • Draws the mc_photo onto a Bitmap object.
  • Call the me/photos Graph API using Facebook.api.
  • Sets the callback to onSaveToPhotoAlbumComplete.
  • Note that you need the publish_stream permission to post to photo album (this is done in the Facebook.login() call in Step 1 and in the JavaScript redirect() function (refer to http://www.permadi.com/blog/2010/01/using-facebook-open-graph-api-in-flash-as3/ to read about how to setup the html page).
[c]
function onSaveToPhotoAlbumClicked(event:MouseEvent)
{
	var bitmapData:BitmapData=new BitmapData(mc_photo.width, mc_photo.height);
	bitmapData.draw(mc_photo);  
	var bitmap:Bitmap=new Bitmap(bitmapData);
	
	var params:Object = {image:bitmap, message:'Test Photo', fileName:'FILE_NAME'};
	Facebook.api('me/photos', onSaveToPhotoAlbumComplete, params);
}
[/c]

The Facebook.api function expects a parameter object containing the bitmap data in the image field.
Note that there is no need to specify the fileName parameter (it isn’t being used by Facebook in the photo album anyway), although you can if you want to.

That’s basically it. It’s that simple.

If you’re wondering how the bitmap gets transmitted to Facebook, take a look at
com.facebook.graph.net.FacebookRequest.as, the call method. It does a smart thing by handling the conversion of the Bitmap object into PNG and passing the PNG data into the POST variable of the me/photos call.

[c]
      /**
        * Makes a request to the Facebook Graph API.
        *
        */
        public function call(method:String,
                             values:* = null,
                             callback:Function = null
                             ):void {

            // OMITTED.........

            //If we have a Bitmap, extract its BitmapData for upload.
            if (fileData is Bitmap) {
				trace("fileData is Bitmap");
                fileData = (fileData as Bitmap).bitmapData;
            }

            if (fileData is ByteArray) {
				trace("fileData is ByteArray");
				
                //If we have a ByteArray, upload as is.
                post.writeFileData(values.fileName,
                                fileData as ByteArray,
                                values.contentType
                                );

            } else if (fileData is BitmapData) {
				trace("fileData is BitmapData");				
                //If we have a BitmapData, create a ByteArray, then upload.
                var ba:ByteArray = PNGEncoder.encode(fileData as BitmapData);
                post.writeFileData(values.fileName, ba, 'image/png');
            }

            post.close();
            urlRequest.contentType =
                    'multipart/form-data; boundary='
                    + post.boundary;

            urlRequest.data = post.getPostData();
            urlRequest.method = URLRequestMethod.POST;
 
           // OMITTED.........
[/c]

Example

You can check the example page at:
http://www.permadi.com/tutorial/as3-save-photo-to-facebook-album/?test

In that example, once you click the SaveToPhotoAlbum button, there will be a message below the button indicating SUCCESS or failure. Upon success, check your Facebook profile page and it should show the status (Profile->Status) like below (the photos are just blue background in this example application — I have posted 3 photos, that’s why you see three):

IMPORTANT UPDATE NOTES

Due to changes on Facebook API, change these elements to get this to work on OAUTH2.0:

  • Change response.session to response.authResponse.
  • Change getSession in .js to getAuthResponse.
  • perms is now called scope.

The source link below has the changes already implemented.

Download link for the example files: http://www.permadi.com/blog/2011/02/using-facebook-graph-api-in-flash-as3-to-post-to-photo-album-download-example-source/

See also: An application example that allows user to save custom image to wall: Easter Your Facebook Friend

9 Responses to “Using Facebook Graph API In Flash AS3 To Post To Photo Album”

  1. [...] Using Facebook Graph API In Flash AS3 To Post To Photo Album [...]

  2. Hello F. Permadi,

    congratulations for these greats posts!

    I have 2 qusetions:

    1 – When I login i Get this message:

    “API Error Code: 191
    API Error Description: The specified URL is not owned by the application
    Error Message: redirect_uri is not owned by the application.”

    but after closing this popup tha app works fine!

    2 – When I login, logout or refresh I get this message:

    “auth.sessionChange”

    Where is this beeing triggered?! How can I remove it?

    Thank you for your time.

  3. Hi Joao,
    the error is usually caused by an incorrect API_KEY. Make sure you have changed the API_KEY in both the php (where it’s called client_id) and in the Action Script. Also check in the Facebook setings page that you have set the Site URL to the folder specified in the redirect_url.

  4. Hi, thank you very much for your tutorial!!!! It works really good!!! But I’m facing a problem when trying to upload a photo to the application album, changing this:

    Facebook.api(‘me/photos’, onSaveToPhotoAlbumComplete, params);

    for the id of the application, example:

    Facebook.api(’108257312581900/photos’, onSaveToPhotoAlbumComplete, params);

    doesn’t work for me… do you have any ideas???

    Thanks in advance!!!!

  5. You’ll likely need a token_id to post to the application page.
    I have not tested posting photos but maybe this tutorial about posting will help:
    http://www.permadi.com/blog/2011/06/facebook-graph-api-posting-feed-to-app-page-as-page/

  6. Hi there Permadi.

    Thanks for the awesome tutorial.

    I only have a question, and it is actually the same as João:
    When I login, logout or refresh I get this message:

    “auth.sessionChange”

    Where is this beeing triggered?! How can I remove it?

    Thanks, see ya.

  7. Hello,

    The applications it´s getting strange.
    It´s is always refreshing/returning to the same page.

    What´s happening?

  8. This has to do with FB now requiring OAUTH 2.0 and deprecating some stuff. See my UPDATE notes in the article above.

  9. This post has been super helpful and It works perfectly!

    Is it possible to post a picture onto a Page’s photo album. Not the user’s album but another Page’s album.

    Basically I am creating an app and when people post their sketch I would love for it to get posted on the users wall (done) but also on another Page’s album so that all the images posted by all users can be in one photo album on another Facebook Page.

Leave a Reply

*