【问题标题】:how to upload image to google cloud storage using python 2.7如何使用 python 2.7 将图像上传到谷歌云存储
【发布时间】:2020-03-19 11:35:18
【问题描述】:

我正在关注本指南:

https://cloud.google.com/appengine/docs/python/googlecloudstorageclient/app-engine-cloud-storage-sample

它只指定了如何上传文本文件,但我想上传图片。 我从前端得到了这个图像数据:

const contentType = 'image/png';

const b64toBlob = (b64Data, contentType='', sliceSize=512) => {
  const byteCharacters = atob(b64Data);
  const byteArrays = [];

  for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    const slice = byteCharacters.slice(offset, offset + sliceSize);

    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    const byteArray = new Uint8Array(byteNumbers);
    byteArrays.push(byteArray);
  }

  const blob = new Blob(byteArrays, {type: contentType});
  return blob;
}

image = b64toBlob(image, contentType);

//the above turns base64 into blobs

var data= new FormData();
data.append('image',image );
data.append('pointerlocation',pointerlocation);

 $.ajax({
    url: "/update",
    data: data,
    processData: false,
contentType: false,
    type: "POST",
   success: function(result) {   
    $("#testimg").attr({ "src": `data:image/png;base64,${image}` });

}
});

这就是我现在在python中得到的

image=self.request.get('image')#gets image
pointerlocation=self.request.get('pointerlocation')#just location of where the image is on my website
upload_file(image,pointerlocation)

def upload_file(image,pointerlocation):
    bucket_name = os.environ.get(
            'mosaictest', app_identity.get_default_gcs_bucket_name())
    bucket = '/' + bucket_name
    filename = bucket + '/'+pointerlocation
    write_retry_params = cloudstorage.RetryParams(backoff_factor=1.1)
    with cloudstorage.open(
            filename, 'w', content_type='image/png',
            retry_params=write_retry_params) as cloudstorage_file:
    #pseudocode-----------------------------------
            cloudstorage_file.addfile(image)
            url=get public url of(filename)
    return url
#---------------------------------------------------

我已经在这个问题上停留了两个多星期,因为谷歌显然放弃了对 python 2.7 的支持,这是唯一接近工作的东西

https://cloud.google.com/storage/docs/reference/libraries

【问题讨论】:

    标签: python-2.7 google-app-engine


    【解决方案1】:

    这就是我如何解决它(字面意思是 3 周的痛苦谷歌搜索) 复制并粘贴下面的函数(不要忘记内容类型,您可以将其设置为 jpeg 或其他任何内容。 无论如何,这个函数将base64数据转换为blob,我将其命名为image blob。

    const contentType = 'image/png';
    const b64toBlob = (b64Data, contentType='', sliceSize=512) => {
      const byteCharacters = atob(b64Data);
      const byteArrays = [];
    
      for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        const slice = byteCharacters.slice(offset, offset + sliceSize);
    
        const byteNumbers = new Array(slice.length);
        for (let i = 0; i < slice.length; i++) {
          byteNumbers[i] = slice.charCodeAt(i);
        }
    
        const byteArray = new Uint8Array(byteNumbers);
        byteArrays.push(byteArray);
      }
    
      const blob = new Blob(byteArrays, {type: contentType});
      return blob;
    }
    
        if(image.substring(0,5)=='data:'){//this if statement determines if the image data is base 64 or not
          image=image.substr(image.indexOf(',') + 1);//strips off the data:/jpeg:base64 thing,so it is pure base64 data
        imageblob = b64toBlob(image, contentType);//converts image to blob
        }
    var data= new FormData();//I created a form for the blob
    data.append('image',imageblob );//add this blob to the form,you can add more if you want, 
    

    现在数据在表单中,我通过 AJAX 将其发送到我的后端

    $.ajax({
        url: "/update",//your handler
        data: data,//<-----this is the form that contains my data
        processData: false,//THESE TWO ARE VERY IMPORTANT!!!!
       contentType: false,//THESE TWO ARE VERY IMPORTANT!!!!
        type: "POST",
       success: function(result) {   
        alert('success!')
    }
    });
    

    所以现在 blob 已发送,我只是使用 this(webbapp2) 获取它

    class update(webapp2.RequestHandler):
     def post(self):
            image=str(self.request.get('image'))#turns image to string, it just works
            imageurl=upload_file(image,'test') #this second parameter is your file name, remember that two files cannot have the same name or something bad might happen
            self.response.write("success")
    
    #just copy and paste this function. 
    import cloudstorage
    import os
    def upload_file(image,filename):
        bucket_name = os.environ.get(
                'default', app_identity.get_default_gcs_bucket_name())
    #i know you can change the bucket, but I have not gotten it to work, so default one it is
        bucket = '/' + bucket_name
        filename = bucket + '/'+filename
        write_retry_params = cloudstorage.RetryParams(backoff_factor=1.1)
        with cloudstorage.open(
                filename, 'w', content_type='image/png',
                retry_params=write_retry_params) as cloudstorage_file:
                    cloudstorage_file.write(image)
        return 'https://storage.cloud.google.com{}'.format(filename)
    

    您必须部署代码才能对其进行测试,要查看图像是否在数据库中,您必须自己检查云存储。只需转到 gcloud,打开左上角的 3 个栏,向下滚动直到到达存储部分,然后单击其中的“存储”,单击浏览器,您应该会看到 2 个存储桶。

    你可能会认为这个答案有点过分,但我并没有为了让另一个人再次遭受同样的命运而遭受 3 周的痛苦。

    如果你的图片没有出现,请开始恐慌。

    【讨论】:

    • 感谢分享适合您的解决方法!
    【解决方案2】:

    您可以尝试将图像作为 blob 上传,如 documentation 所示,以下代码将适用于您:

    def upload_blob(bucket_name, source_file_name, destination_blob_name):
        """Uploads a file to the bucket."""
        storage_client = storage.Client()
        bucket = storage_client.get_bucket(bucket_name)
        blob = bucket.blob(destination_blob_name)
    
        blob.upload_from_filename(source_file_name)
    
        print('File {} uploaded to {}.'.format(
            source_file_name,
            destination_blob_name))
    

    您只需提供存储桶名称、源文件名称以及将写入存储桶的文件名称。

    【讨论】:

    • 这对我不起作用,因为我做不到:从 google.cloud 导入存储。显然已经放弃了对此的支持,我找到了另一种方法
    猜你喜欢
    • 2013-11-30
    • 1970-01-01
    • 2017-12-04
    • 2015-02-28
    • 2018-02-15
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多