Posting an image on a platform which requires it to be of a ‘multipart/form-data’ content type is different from posting a URL link of an image or sending an image as binary data.
For example, both Flickr and Facebook APIs require the ‘multipart/form-data’ type for uploading images and in the latter case I never realized it because there was an existing Facebook API which was doing the work behind the scenes.
Incase of Facebook, if you are using the Facebook Actionscript3 SDK for posting images to your own wall, you are required to convert your image into a ByteArray and then use the API to POST the image. The classes that handle this are the FacebookRequest.as, AbstractFacebookRequest.as and PostRequest.as, but as a developer you may never know of these classes or use them directly.
For instance the code below captures a Movieclip from the stage as a bitmap, encodes it as a PNG and then uploads it to your Facebook wall using the Facebook Actionscript3 SDK.
1 2 3 4 5 6 7 8 |
var bitmapD:BitmapData = new BitmapData(movieClip.width,movieClip.height); bitmapD.draw(movieClip); var imageStream = PNGEncoder.encode(bitmapData); bitmapD.dispose(); var values:Object = {message:"A test to post image" , fileName:'anyname.jpg' , image:imageStream}; FacebookMobile.api('/me/photos', onCheckResult, values,'POST'); |
In my case I did not have any SDK or classes to work with this particular content type. That’s when I read about the UploadPostHelper.as class written by Jonathan Marston. It is an old class written in 2007 so it needed minor modifications to work with today, but nonetheless, it served the purpose of building a POST request with properly formatted headers required by the server to interpret the content of multipart/form-data type.
Assuming if I had to rewrite the code to post an image to Facebook without an SDK, the code below would work just as well.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
var bitmapD:BitmapData = new BitmapData(movieClip.width,movieClip.height); bitmapD.draw(movieClip); var imageStream = PNGEncoder.encode(bitmapData); bitmapD.dispose(); postData(); function postData():void{ var loader:URLLoader = new URLLoader(); var urlRequest:URLRequest = new URLRequest(); var variables:URLVariables = new URLVariables(); urlRequest.url = "https://graph.facebook.com/me/photos"; urlRequest.contentType = "multipart/form-data; boundary=" + UploadPostHelper.getBoundary(); urlRequest.method = URLRequestMethod.POST; var postVariables:Object = {} if (this.accessToken != ""){ postVariables.access_token = this.accessToken; } postVariables.message = "A test to post image"; urlRequest.data = UploadPostHelper.getPostData("anyname.jpg", imageStream, postVariables); urlRequest.requestHeaders.push( new URLRequestHeader( 'Cache-Control', 'no-cache' ) ); loader.dataFormat = URLLoaderDataFormat.BINARY; loader.load(urlRequest); } |
Write to me if you want the UploadPostHelper.as class with the changes I’ve made to it or have suggestions to work with image data.
Mariam
Hi
I’m trying to upload photo with Twitter API that also requires multipart/form-data
https://dev.twitter.com/docs/api/1.1/post/statuses/update_with_media
Used OAuth to login and can post status without problems, using your example to upload a photo I’m getting Stream Error over and over again
Error #2032: Stream Error. URL: https://api.twitter.com/1.1/statuses/update_with_media.json?oauth_consumer_key=XXXXX&oauth_nonce=XXXX&oauth_signature=XXXXX&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1376673067&oauth_token=XXXX-XXXXX
Here is my code
//image is a JPG encoded ByteArray
var params:Object = {};
params.status = status;
token = new OAuthToken(twitterSO.data.twitter.accessKey, twitterSO.data.twitter.accessSecret);
var postRequest:OAuthRequest = new OAuthRequest(OAuthRequest.HTTP_MEHTOD_POST, API_URL + “statuses/update_with_media.json”, null, oAuthConsumer, token);
var urlRequest:URLRequest = new URLRequest(postRequest.buildRequest(new OAuthSignatureMethod_HMAC_SHA1()));
urlRequest.method = URLRequestMethod.POST;
urlRequest.contentType = ‘multipart/form-data; boundary=’ + UploadPostHelper.getBoundary();
urlRequest.method = URLRequestMethod.POST;
urlRequest.data = UploadPostHelper.getPostData(“image.jpg”, image, params);
urlRequest.requestHeaders.push(new URLRequestHeader(“Cache-Control”, “no-cache”));
var urlLoader:URLLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.load(urlRequest);
Don’t know if my problem could be that changes that you mention on UploadPostHelper.as
Can you give me a hand?
Thanks in advance
Probably this way is much more clear 🙂
public function postImageToTwitter(status:String, image:ByteArray, latitude:String = “”, longitude:String = “”):void
{
token = new OAuthToken(twitterSO.data.twitter.accessKey, twitterSO.data.twitter.accessSecret);
var postRequest:OAuthRequest = new OAuthRequest(OAuthRequest.HTTP_MEHTOD_POST,
API_URL + “statuses/update_with_media.json”, null, oAuthConsumer, token);
postRequest.buildRequest(new OAuthSignatureMethod_HMAC_SHA1());
var params:Object = new Object();
params.status = status;
params.lat = latitude;
params.lon = longitude;
params.oauth_consumer_key = postRequest.requestParams.oauth_consumer_key;
params.oauth_nonce = postRequest.requestParams.oauth_nonce;
params.oauth_signature = postRequest.requestParams.oauth_signature;
params.oauth_signature_method = postRequest.requestParams.oauth_signature_method;
params.oauth_timestamp = postRequest.requestParams.oauth_timestamp;
params.oauth_token = postRequest.requestParams.oauth_token;
var urlRequest:URLRequest = new URLRequest();
urlRequest.url = API_URL + “statuses/update_with_media.json”;
urlRequest.contentType = “multipart/form-data; boundary=” + UploadPostHelper.getBoundary();
urlRequest.method = URLRequestMethod.POST;
urlRequest.data = UploadPostHelper.getPostData(“image.jpg”, image, params);
urlRequest.requestHeaders.push(new URLRequestHeader(‘Cache-Control’, ‘no-cache’));
var urlLoader:URLLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.addEventListener(Event.COMPLETE, onTwitterPostComplete);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onTwitterIOError);
urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onTwitterHttpStatus);
urlLoader.load(urlRequest);
}
On API documentation says this (‘Your POST request’s Content-Type should be set to multipart/form-data with the media[] parameter’) but dont know what it means
Appreciate a lot if you can help me 🙂
dear Mariam,
Thanks for this post. I think it gonna save my day as I am building an app for Facebook from flash. May I get your modified UploadPostHelper.as
Thanks a lot! 🙂
Hi!
it’s exactly what i’m looking for! Could you please share your UploadPostHelper code?
Thanks
thank you for this post, Could you pls send me your modified UploadPostHelper code to convert a bitmapData to a multipart-form/data image… Thank you! I’m stucked with this for over a week!