cohenadair
cohenadair

Reputation: 2072

Using PhoneGap + Google App Engine to Upload and Save Images

Goal: Take/attach pictures in a PhoneGap application and send a public URL for each picture to a Google Cloud SQL database.

Question 1: Is there a way to create a Google Cloud Storage object from a base64 encoded image (in Python), then upload that object to a bucket and return a public link?

I'm looking to use PhoneGap to send images to a Python Google App Engine application, then have that application send the images to a Google Cloud Storage bucket I have set up, then return a public link back to the PhoneGap app. These images can either be taken directly from the app, or attached from existing photo's on the user's device.

I use PhoneGap's FileTransfer plugin to upload the images to GAE, which are sent as base64 encoded images (this isn't something I can control).

Based on what I've found in Google Docs, I can upload the images to Blobstore; however, it requires <input type='file'> elements in a form. I don't have 'file' input elements; I just take the image URI returned from PhoneGap's camera object and display a thumbnail of the picture that was taken (or attached).

Question 2: Is it possible to have an <input type='file'> element and control it's value? As in, is it possible to set it's value based on whether the user chooses a file, or takes a picture?

Thanks in advance!

Upvotes: 1

Views: 629

Answers (2)

cohenadair
cohenadair

Reputation: 2072

Here's a solution for others who might face this problem. Turns out it's incredibly simple!

Once you have a bucket setup for your GAE project, you can use this Python code to send an image to the bucket:

import cloudstorage as gcs
import webapp2
import cgi
import MySQLdb
import os
import logging
import time

from google.appengine.api import mail
from google.appengine.api import images
from google.appengine.ext import blobstore

class UploadImageHandler(webapp2.RequestHandler):
    def post(self):
        self.response.headers.add_header(ACCESS_CONTROL, '*')

        f = self.request.POST['image']
        fname = '/your-bucket-name/%s' % f.filename;

        gcs_file = gcs.open(fname, 'w', content_type="image/jpeg")
        gcs_file.write(self.request.get('image'))
        gcs_file.close()

And the code used to upload the file from a PhoneGap application:

// Uploads images in "imageURIs" to the web service specified in "server".
function uploadImages(imageURIs, server) {
    var success = function(data) {
        alert("Successfully uploaded image!");
    };

    var fail = function(error) {
        alert("Failed to upload image: "+error);
    };

    var options = new FileUploadOptions();
    options.fileKey = "image";
    options.mimeType = "image/jpeg";
    var ft = new FileTransfer();

    for (var i = 0; i < imageURIs.length; i++) {
        alert("Uploading"+i);
        options.fileName = imageURIs[i].substr(imageURIs[i].lastIndexOf('/') + 1);
        ft.upload(imageURIs[i], encodeURI(server), success, fail, options);
    }
}

I hope it helps someone else. :)

Upvotes: 2

GAEfan
GAEfan

Reputation: 11360

Yes, that is a fine use for GAE and GCS. You do not need an <input type=file>, per se. You can just set up POST parameters in your call to your GAE url. Make sure you send a hidden key as well, and work from SSL-secured urls, to prevent spammers from posting to your app.

Upvotes: 0

Related Questions