views:

2427

answers:

7

Hello all,

I wish to upload from my Flash Application (AS3) to imageshacks XML API. I wish to know how I can do this.

"In Flash, we must POST the data using the UrlRequest and UrlLoader classes, however we run into a limitation of the Flash API. The data property of a UrlRequest can either be a UrlVariablesByteArray object. There is no easy way to send name value pairs along with the JPG byte array. This is a big problem, because most upload applications will require a filename and other headers to accompany the raw file data"

I was hoping if someone could help me overcome the above!

Thanks all

Update

I have tried making use of this tutorial here:http://www.mikestead.co.uk/2009/01/04/upload-multiple-files-with-a-single-request-in-flash/

The problem is it's not for unsaved images, but it get images from your local machine and then uploads it to the server where the images has had a name already!

A: 

Hi,

I haven't used the imageshack API, but I've sent BitmapData to a server before.

You need to create an URLRequest and add the bitmapData as a byteArray, so the code, I guess, would look something like:

var header:URLRequestHeader = new URLRequestHeader ("Content-type", "application/octet-stream");//this says the data your sending is binary, not text
var uploadRequest:URLRequest = new URLRequest('yourImageShackUploadURL.php');
uploadRequest.requestHeaders.push (header);
uploadRequest.method = URLRequestMethod.POST;
uploadRequest.data = yourBitmapData.getPixels(yourBitmapData.rect);

sendToURL( uploadRequest);

You might need the following imports:

import flash.net.* // for sendToURL and other net stuff
import flash.geom.Rectangle;
import flash.display.BitmapData;

You get a ByteArray from your bitmapData using the BitmapData's getPixels() method. It needs a Rectangle instance for to know the position and dimensions you need, but if you want the ByteArray for all the BitmapData, not just a part of your, you can use the BitmapData's rect property. You create a header using the URLRequestHeader class and you push it into the requestHeaders of your URLRequest. You specify your method is post using the method property.

This should be it. I'm not aware of any other API specific stuff, so hope this helps.

Good luck!

George Profenza
Read the question thoroughly, he knows how to do what you just posted, he's asking how to send a ByteArray AND extra post vars for the image name, etc, because the common method (the one you have just shown) only allows that one variable when sending binary!
Bryan Grezeszak
Bryan is correct.
Abs
A: 

I haven't used the imageshack API, but you may want to try using adobe's JPGEncoder class - here's a quick example that passes a username and the JPG's byte array, it's really quite simple.

private function savePicToServer(bmpData:BitmapData):void
{
    var jpgEncoder:JPGEncoder = new JPGEncoder(85);
    var jpgStream:ByteArray = jpgEncoder.encode(bmpData);

    var loader:URLLoader = new URLLoader();
        configureListeners(loader);

    var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
    var request:URLRequest = new URLRequest(ModelLocator.BASE_URL + ModelLocator.UPLOAD_URL + "?user=" + ModelLocator.getInstance().username);
    request.requestHeaders.push(header);
    request.method = URLRequestMethod.POST;
    request.data = jpgStream;
    loader.load(request);
}

Note that the variables are passed as part of the query string. You can't use URLVariables, as several people have suggested, as the URLVariables would be stored in the request's data property, which we are already using to pass the byteArray.

quoo
A: 

Hi i don't really get the problem of the question, anyway: If the question is how to send the name of the file and the extension (image type) from flash toghether with the byteArray of image data you should use a URLVariables object.

This object could also send the query string as byte instead of text.

var request:URLRequest = new URLRequest();
request.url = "your_server_page_for_example.php";
request.method = URLRequestMethod.POST;

var variables:URLVariables = new URLVariables();
variables.name = "imgName";
variables.type = ".jpg";
variables.image = myByteArray;

request.data = variables;
+1  A: 

This was of great help to me: http://www.quietless.com/kitchen/upload-bitmapdata-snapshot-to-server-in-as3/

You need to modify the URLRequestWrapper to insert field names and file names where needed. Here's what I've done:

bytes = 'Content-Disposition: form-data; name="' + $fieldName + '"; filename="';

It does the most formatting of headers so the server could understand it as a file upload.

By the way, if you have a BitmapData you might need to encode it to JPEG or PNG first.

Regards, Artem

artemb
+1  A: 

You can send your filename data and any other data you want along with the URLRequest:

var params:URLVariables = new URLVariables();
params.id = ride.id;
params.filename = ride.map_image;
params.path = 'maps/';
var req:URLRequest = new URLRequest( ModelLocator.SERVER_URL + "/php/uploadpic.php");
req.method = URLRequestMethod.GET;
req.data = params;
fileRef.upload(req);

on the server side in php you access the extra variables as: $_REQUEST['path'] and $_REQUEST['filename'] etc

Gary Benade
I believe fileReference requires you to call fileReference.browse() before you can upload a file, it wouldn't work if you're trying to create an image.
quoo
A: 

You can use URLVariables, just base64-encode bytearray so it's not binary data:

import mx.utils.Base64Encoder;
// ...
var urlRequest:URLRequest = new URLRequest("/whatever");
urlRequest.method = URLRequestMethod.POST;
var urlVariables:URLVariables = new URLVariables();
var base64Encoder:Base64Encoder = new Base64Encoder();
base64Encoder.encodeBytes(byteArray);
urlVariables.something_base64 = base64Encoder.toString();
urlRequest.data = urlVariables;
navigateToURL(urlRequest, "_blank");

then on server side base64decode '' post field, ie:

php:

base64_decode($_POST['something_base64'])

rails:

require 'base64';
# ...
Base64.decode64(params[:something_base64])
Mirek Rusin