1

I am trying to upload a photo, after being cropped by croppie into the GCS. The gcs write(imageToUpload) method fails because imageToUpload isn't currently a file, but rather a BLOB. Does anyone know a way to make this work? Perhaps, a way in python to convert a BLOB to a file? The image types that can be returned from Croppie are: 1) Canvas, 2) HTML, 3) BLOB and 4)Base64 Here is the documentation (Ctrl-F "Result"). Any help would be much appreciated!

user123429
  • 187
  • 1
  • 8

3 Answers3

0

You can use the images pkg in App Engine.

from google.appengine.api import images
import urllib2

# if you fetch as image
image        = urllib2.urlopen(the_image_url)   
content_type =  image.headers['Content-Type'] 
image_bytes  = image.read()
image.close()

# if you fetch as bytes
image_bytes  = urllib2.urlopen(the_image_bytes_url) 
content_type = my_image_file.content_type  

filename = '/{}/user/{}_avatar'.format(DEFAULT_GCS_BUCKET_NAME), user_id) # for example

'''
    Create a GCS file with GCS client.
    Make sure you give the GAE app permission to write to your bucket:
    https://developers.google.com/appengine/docs/python/googlestorage/index#Prerequisites
'''

options={'x-goog-acl': 'public-read', 'Cache-Control': 'private, max-age=0, no-transform'}
with gcs.open(filename, 'w', content_type=content_type, options=options) as f:
    f.write(image_bytes)
    f.close()
GAEfan
  • 11,244
  • 2
  • 17
  • 33
  • This is getting close, but it's still not working 100%. Do you mind going into a little more detail on the the first line "my_image_file.read()" and of the 4 options I mentioned in my original question, what data format should I be using? Base64? – user123429 Apr 23 '18 at 14:44
  • Are you given a URL for the image? Or its bytes? I have edited the answer with code to fetch from a url – GAEfan Apr 23 '18 at 15:43
  • hmm will it isn't a url, but rather think a `imagedata = _some base64data`, and i can't figure out how to turn imagedata into a image file to store on google cloud storage – user123429 Apr 24 '18 at 02:19
  • Did you try writing the data, as `image_bytes`, per the last lines of code in my answer? – GAEfan Apr 24 '18 at 04:24
0

All you really need to do is just convert the base64 format into a local file so you can upload it.

Please check out this post for details.

Ying Li
  • 2,500
  • 2
  • 13
  • 37
  • I feel like a complete idiot... I'm using the following code to create my file, but it is breaking at _open_. Does GAE not support _open_? `img_data = b'iVB.... fh = open("imageToSave.png", "wb") fh.write(img_data.decode('base64')) fh.close()` – user123429 Apr 24 '18 at 02:17
  • No, GAE does not support anything that opens local files. You have to use a FileStream not an actual file in order for it to work. – Ying Li Jun 06 '18 at 23:14
0

My solution is in PHP but I think you will be able to get the idea and convert it to python.

Croppie Result Method:-

logoCropper.croppie('result', {
    type: 'base64',
    size: 'viewport'
})
.then(function (resp) {
   // sends the data to the server using an AJAX call
   // AJAX call data 
   //     data: {
   //       'imagebase64': resp
   //     }
});

PHP Endpoint:-

$imageName = $some_name.".png";

// extracting the base64 encoded string from the request payload
$imageArray = explode(";", $request->get('imagebase64'));
$imageContents = explode(",", $imageArray[1]);

$imagebase64 = base64_decode($imageContents[1]);

// saving the image to a temp file
$tempPath = sys_get_temp_dir()."/".$imageName;
file_put_contents($tempPath, $imagebase64);

$storageClient = new StorageClient([
        'projectId' => $project_id,
        'keyFilePath' => $credentials_path,
]);

$bucket = $storageClient->bucket($bucketName);
$adapter = new GoogleStorageAdapter($storageClient, $bucket);

$filesystem = new Filesystem($adapter);

// uploading to the google bucket
$stream = fopen($tempPath, 'r+');
$filesystem->writeStream($storage_folder."/".$imageName, $stream, [
        'visibility' => AdapterInterface::VISIBILITY_PRIVATE,
        'metadata' => [
            'contentDisposition' => "attachment; filename={".$imageName."}",
            'ContentType' => "image/png"
        ]
    ]);
Dula
  • 1,276
  • 5
  • 14
  • 23