« Xml Generation Module | Main | Binding Selected Items in a Flex List »

Sending Images From Flex to a Server

Today's challenge has been to allow a Flex app to create images, and have the new images uploaded back to the server as a bitmap. The application is for a simple buddy-icon editing application: users can upload their photos, drag in bits of clip art, resize and so on, then use their generated buddy icon on the site. The same could be useful for doing basic image editing, uploading for print.

There are two issues. First is getting uploaded images into Flex. That's a topic for a future post (but basically you have to upload them to the server, then download them again).

The second is uploading a final image generated by Flex. And it turns out this is surprisingly easy.

Flash has the ability to render any display component to a bitmap, using the BitmapData class. So in my graphic-design-canvas component I did:

private var bitmapData:BitmapData; 
private function saveToBitmap():void 
{ 
    bitmapData = new BitmapData(48, 48, true, 0x00ffffff); 
    bitmapData.draw(this);

The next stage was to convert the raw bitmap data into an image format (to reduce bandwidth requirements). In Flex 2.01 I used Adobe's PNGEncoder from their corelib package. Once you've set up a classpath, or copied the .swc file into /frameworks/lib, you can do this:

    var imageData:ByteArray = PNGEncoder.encode(bitmapData);

Easy as pie.

Finally to send it to the server I use a POST HTTP request. This requires that the bitmap data is encoded in Base 64:

    var encoder : Base64Encoder = new Base64Encoder(); 
    encoder.encodeBytes(imageData); 
    var params:Object = { image_data: encoder.flush() }; 
    imageSend.send(params); 
}

where imageSend is the name of a HTTPService I created:

<mx:HTTPService id="imageSend" showBusyCursor="true" 
 useProxy="false" url="http://www.example.com/upload_image/" 
 method="POST" result="imageSentConfirmation()"/>

Which is all very neat and simple: 8 lines of code.

On the Django end you simply need to extract the data from request.POST and decode the base-64 coded string:

def upload_image(request): 
    data = base64.b64decode(request.POST['image_data'])
You can feed this data into a file directly:
    open("filename.png", "wb").write(data)

or send it to the Python Imaging Library for size-checks, conversion, or other jiggery pokery:

    img = Image.open(StringIO(data)) 
    img = img.resize((48,48), Image.ANTIALIAS) 
    img.save(os.path.join(MEDIA_ROOT, "filename.png"))

Then return something that your Flex component understands:

    return http.HttpResponse("<ok/>", mimetype="text/xml")

Of course, you'll probably want to do some more error handling on the server: trapping garbage content, file issues and the like. But the basic functionality is yours for just two lines of Django code!

TrackBack

TrackBack URL for this entry:
http://www.icosagon.com/mt/mt/mt-tb.cgi/162

Comments

I'm actually just starting a project of converting an existing site (PHP) to Django - and hope to be using Flex quite religously.

The first part of the project is to build something very similar to what you're doing - a PDF builder basically (something like business cards). I'd love to take a look at what you developed if possible and maybe pick your brain a bit on how you work with flex/django together.

not too much information on the topic... thanks for having a blog that's focused on dealing with these issues.

feel free to drop me a line.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)