简体   繁体   中英

How to upload an image to Google Cloud Storage from App Engine

I'm trying to take a base64-encoded PNG, decode it, then upload it to Google Cloud Storage and get its public URL.

I can do it locally by saving the PNG to file and then uploading it with blob.upload_from_file('picture.png') , but App Engine doesn't allow write access to its file structure.

This code works locally but not in Google App Engine, where it fails at with open(...

import base64
from google.cloud import storage

def handler(request):

    pic = request.POST.get('photograph') #Object like 'data:image/png;base64,iVBORw0KGgoAAAAN…'
    data = pic[22:]                
    png = base64.b64decode(data)     
    filename = "pic.png" 
    with open(filename, "wb") as f:
        f.write(png)
    client = storage.Client.from_service_account_json(os.path.abspath('credentials.json'))
    bucket = client.get_bucket('mybucket')
    blob = bucket.blob(filename)        #create destination uri in bucket
    blob.upload_from_file(filename)       

    image_url = "https://storage.googleapis.com/mybucket/" + filename

The GCS docs say to Use the Blob.upload_from_file(), Blob.upload_from_filename(), or Blob.upload_from_string() method to upload an object.

However none of those methods work for this situation because there is no file, just an encoded PNG object. How can I upload it to gcloud storage?

I'm surely missing something obvious. Any ideas would be much appreciated.

As per David's suggestion, this is what worked. I simply added /tmp/ before the filename and App Engine allowed me to save it.

import base64
from google.cloud import storage

def handler(request):
    pic = request.POST.get('photograph') 
    data = pic[22:]                
    png = base64.b64decode(data)     
    filename = "pic.png"

    temp_location = '/tmp/' + filename          #here
    with open(temp_location, "wb") as f:        
        f.write(png)

    client = storage.Client.from_service_account_json(os.path.abspath('credentials.json'))
    bucket = client.get_bucket('mybucket')
    blob = bucket.blob(filename)        
    blob.upload_from_file(temp_location)       

    image_url = "https://storage.googleapis.com/mybucket/" + filename
import base64
from google.cloud import storage 
#The post_image_base64 is base64 string
base64_img_bytes = post_image_base64.encode('utf-8')

#this for localhost if you want to upload it to gcloud storage then you have to add this path /tmp/ 

"""
with open('/tmp/'+'decoded_image.png', 'wb') as file_to_save:
   decoded_image_data = base64.decodebytes(base64_img_bytes)
"""
with open('decoded_image.png', 'wb') as file_to_save:
   decoded_image_data = base64.decodebytes(base64_img_bytes)
   ##Save file 
   #file_to_save.write(decoded_image_data)


gcs=storage.Client.from_service_account_json(os.path.abspath('credentials.json'))  
bucket = gcs.get_bucket("bucket_name")
blob = bucket.blob("image_name.png")

#for upload to gcloud storage you also need to add /tmp/ path in here
#blob.upload_from_string("/tmp/"+decoded_image_data)

blob.upload_from_string(decoded_image_data)

#and then make it public use this
blob = bucket.get_blob('image_name.png')
blob_url = blob.make_public()            
print(blob.public_url);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM