views:

615

answers:

3

I know that I can accept image uploads by having a form that POSTs to App Engine like so:

<form action="/upload_received" enctype="multipart/form-data" method="post">
<div><input type="file" name="img"/></div>
<div><input type="submit" value="Upload Image"></div>
</form>

Then in the Python code I can do something like

image = self.request.get("img")

But how can I figure out what the content-type of this image should be when later showing it to the user? It seems the most robust way would be to figure this out from the image data itself, but how to get that easily? I did not see anything suitable in the google.appengine.api images package.

Should I just look for the magic image headers in my own code, or is there already a method for that somewhere?

Edit:

Here's the simplistic solution I ended up using, seems to work well enough for my purposes and avoids having to store the image type as a separate field in the data store:

# Given an image, returns the mime type or None if could not detect.
def detect_mime_from_image_data(self, image):
    if image[1:4] == 'PNG': return 'image/png'
    if image[0:3] == 'GIF': return 'image/gif'
    if image[6:10] == 'JFIF': return 'image/jpeg'
    return None
A: 

Based on my research, browsers, except for Internet Explorer (version 6 at least), determine the file mime type by using the file's extension. Given that you want image mime types, you could use a simple Python dictionary in order to achieve this.

Unfortunately I don't know of any method in Python that tries to guess the image type by reading some magic bytes (the way fileinfo does in PHP). Maybe you could apply the EAFP (Easier to Ask Forgiveness than Permission) principle with the Google appengine image API.

Yes, it appears that the image API does not tell you the type of image you've loaded. What I'd do in this case is to build that Python dictionary to map file extensions to image mime types and than try to load the image while expecting for a NotImageError() exception. If everything goes well, then I assume the mime type was OK.

Ionuț G. Stan
+4  A: 

Instead of using self.request.get(fieldname), use self.request.POST[fieldname]. This returns a cgi.FieldStorage object (see the Python library docs for details), which has 'filename', 'type' and 'value' attributes.

Nick Johnson
A: 

Try the python mimetypes module, it will guess the content type and encoding for you,

e.g.

>>import mimetypes

>>mimetypes.guess_type("/home/sean/desktop/comedy/30seconds.mp4")

('video/mp4', None)

Sean O Donnell