Flickr provides developers with the ability to upload images into a user account similar to how Facebook does. However, the standard API effectively only allows posting from an image file. A problem arises when the image you want to post is a snapshot taken by Flex from inside your SWF. Flickr does not accept raw image data from the Flash Player so you have to use a PHP script or similar to deal with the raw data, create an image and send it to Flickr. This is how it can done:
1. Authenticate User with Flickr
- Download the latest ActionScript API for Flickr and put the ‘com’ folder into your project
- This page explains how you can get a user to authenticate with Flickr and obtain a token for your application. The fix posted by rrossen on Feb 25, 2008 is especially useful.
- Make sure to save the obtained token to a variable in Flex.
2. Create a snapshot inside the Flex movie and send it to a PHP script
As an example, the following code captures content of a canvas called ‘preview’
import mx.graphics.codec.JPEGEncoder;
import mx.graphics.ImageSnapshot;
...
var snapshot:ImageSnapshot = ImageSnapshot.captureImage(preview, 0, new JPEGEncoder());
Send encoded image data to a PHP script e.g. using Cairngorm.
In the FlickUploadPhoto command:
var request : Object = new Object();
var flickrUploadPhotoEvent:FlickrUploadPhotoEvent = event as FlickrUploadPhotoEvent;
//Convert to Base64
var encoder:Base64Encoder = new Base64Encoder();
encoder.encodeBytes(flickrUploadPhotoEvent.imageData.data);
request.imageData = encoder.toString();
//send the app key, app secret and token as well so that the PHP script can send an authenticated request to Flickr:
request.appKey = flickrUploadPhotoEvent.appKey;
request.appSecret = flickrUploadPhotoEvent.appSecret;
request.token= flickrUploadPhotoEvent.token;
// set request to service
service.request = request;
// dispatch call
var call : Object = service.send();
call.addResponder(this);
3. Create a REST controller that will handle the request
- Download PHP Flickr API (current latest version: PHP5) and add the PHP files into your project
- Inside of the function that handles the request in your REST controller: decode the image data, create a temporary image and send it to the Uploader class of the Flickr API for further handling:
$imageData = $this->input->post('imageData');
$appKey = $this->input->post('appKey');
$appSecret = $this->input->post('appSecret');
$token = $this->input->post('token');
$myImage = base64_decode($_POST['imageData']);
if ($myImage != false)
{
//Write the image to a file
$tmpfname = tempnam("", "FC");
$handle = fopen($tmpfname, "w");
fwrite($handle, $myImage);
fclose($handle);
//request FlickrUploader to handle the upload:
$uploader = new Phlickr_Uploader();
$uploader->setPerms(0,1,0); //friends only
$uploader->setAuthenticationParams($appKey,$appSecret,$token);
$id = $uploader->upload($tmpfname,"Puma KingOf","");
if ($id >= 0)
{
//handle successfull upload
}
else
{
//handle error
}
//get rid of the file
unlink($tmpfname);
}
4. Change Upload.php located in the PHP Flickr API
Make the following changes to Upload.php in the Phlickr folder so that the class is more standalone:
//add variables that will hold the security data
protected $_appKey = "";
protected $_appSecret = "";
protected $_appToken = "";
//add function that will save the security data:
public function setAuthenticationParams($appKey,$appSecret,$token) {
$this->_appKey = $appKey;
$this->_appSecret = $appSecret;
$this->_token = $token;
}
Changes to make in the upload function:
...
$params = array(
'api_key' => $this->_appKey,
'auth_token' => $this->_token,
'title' => $title,
...
$params['api_sig'] = md5($this->_appSecret . $signing);
...
$result = Phlickr_Request::SubmitHttpPost(self::UPLOAD_URL, $params, self::TIMEOUT);
// use the reponse object to parse the results
try
{
$resp = new Phlickr_Response($result, true);
}
catch (Exception $e)
{
//return error code
return -1;
}
// return a photo id
return (string) $resp->getXml()->photoid;
The above code sets the name and description of the uploaded image to ‘test’. It would be possible to send these parameters from Flex or just hard-code them to anything else.
The PHP Flickr API also provides a function for batch upload images which might be useful e.g. for a gallery managed by Flex.