Reputation: 2072
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
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
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