Main | July 2007 »

June 30, 2007

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!

June 29, 2007

Xml Generation Module

In all my apps I communicate client to server in XML. Flex has very nice XML processing capabilities through e4x. I typically generate only simple XML to send back to the server, where python's processing is fairly easy too.

The last link in the chain is getting Django to generate XML easily. I wrote a very simple xml generating module that might proove useful.

It is designed to be as simple as possible. So you might have

>>> b = xml.book( 
...     xml.title('The Title'), xml.author('Ian Millington') 
...     )

and have it rendered to xml with:

>>> b.xml 
'<book><title>The Title</title><author>Ian 
Millington</author></book>'

Of course, things can get much more complex, it handles tag properties, namespaces, DTDs and so on. For example:

>>> svg = XMLNamespace('svg', 'http://www.w3.org/2000/svg') 
>>> makeXhtml(html.html(html.body(svg.svg(), class='main-page')))
produces
<?xml version="1.0"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns:svg="http://www.w3.org/2000/svg"> 
<body class="main-page"> 
<svg:svg/> 
</body> 
</html>

You can find the python module on google code here, with the actual python code here. The license is LGPL (i.e. no warranties, free for commercial use, non-copyleft).

The code is based on a HTML code generator I wrote as part of a research project last year. That in turn was inspired by the HTML creation system in MochiKit, which is in turn based on a Python HTML library, I believe, but I don't know which one. Please fill me in on the missing inspiration if you know. In any case I think that the prior art used a fixed set of tag functions, rather than allowing any tags to be used. Correct me if I'm wrong!

EDIT: The module bears a striking resemblance to XIST (thanks for the pointer Tom!). XIST seems to be slightly more complex to get going, but lots more capable too.

June 28, 2007

Welcome

Welcome to Django'n'Flex. This site is about working with these two great new technologies, because that's what I'm doing a lot at the moment.

I thought I'd start this blog to note down things I've found out, numskull moments and the rare bit of insight.