如何在 Google 数据实验室中打开存储在 GCP 中的图像?

How do I open images stored in GCP in Google datalab?

我一直在尝试打开存储在我的数据实验室笔记本的 GCP 存储桶中的图像。当我使用 Image.open() 它说 "No such file or directory: 'images/00001.jpeg'"

我的代码是:

nama_bucket = storage.Bucket("sample_bucket")
for obj in nama_bucket.objects():
    Image.open(obj.key)

我只需要打开存储在存储桶中的图像并查看它。感谢您的帮助!

我能够重现该问题并得到与您相同的错误(没有这样的文件或目录)。

我将描述我用来解决它的解决方法。但是,在提供的代码片段中我可以看到一些问题:

  • Class IPython.display.Image 没有方法 'open'.

  • 您需要将 Image 构造函数包装在 display() 方法中。

使用 Storage APIs for Google Cloud Datalab,为我解决问题的方法是使用 url 参数而不是 文件名

这是对我有用的解决方案

import google.datalab.storage as storage
from IPython.display import Image

bucket_name = '<my-bucket-name>'
sample_bucket = storage.Bucket(bucket_name)

for obj in sample_bucket.objects():
    display(Image(url='https://storage.googleapis.com/{}/{}'.format(bucket_name, obj.key)))

如果有帮助请告诉我!


编辑 1:

正如您提到的,您正在使用 PIL 并希望它处理您的图像,这是实现该目的的方法(我已经对其进行了测试并且效果很好对我来说):

import google.datalab.storage as storage
from PIL import Image
import requests
from io import BytesIO

bucket_name = '<my-bucket-name>'
sample_bucket = storage.Bucket(bucket_name)

for obj in sample_bucket.objects():
    url='https://storage.googleapis.com/{}/{}'.format(bucket_name, obj.key)
    response = requests.get(url)
    img = Image.open(BytesIO(response.content))
    print("Filename: {}\nFormat: {}\nSize: {}\nMode: {}".format(obj.key, img.format, img.size, img.mode))
    display(img) 

请注意,这样您将根本不需要使用 IPython.display.Image


编辑 2:

的确,出现错误 cannot identify image file <_io.BytesIO object at 0x7f8f33bdbdb0> 是因为您的存储桶中有一个目录。为了解决这个问题,了解 Google 云存储 sub-directories 的工作原理很重要。

以下是我在 存储桶 中组织文件以复制您的情况的方式:

my-bucket/
    img/
        test-file-1.png
        test-file-2.png
        test-file-3.jpeg
    test-file-4.png

尽管 gsutil 通过应用各种规则来实现分层 文件树 错觉,以尝试使命名以用户的方式工作事实上,测试文件 1-3 恰好在名称中包含“/”,而 没有实际的 'img' 目录 .

您仍然可以列出存储桶中的所有图像。使用我上面提到的结构,对于 example,可以通过检查文件的扩展名来实现:

import google.datalab.storage as storage
from PIL import Image
import requests
from io import BytesIO

bucket_name = '<my-bucket-name>'
sample_bucket = storage.Bucket(bucket_name)

for obj in sample_bucket.objects():
    # Check that the object is an image
    if obj.key[-3:].lower() in ('jpg','png') or obj.key[-4:].lower() in ('jpeg'):
        url='https://storage.googleapis.com/{}/{}'.format(bucket_name, obj.key)
        response = requests.get(url)
        img = Image.open(BytesIO(response.content))
        print("Filename: {}\nFormat: {}\nSize: {}\nMode: {}".format(obj.key, img.format, img.size, img.mode))
        display(img)

如果您只需要获取存储桶中“存储在特定子目录”中的图像,您还需要按名称检查文件:

import google.datalab.storage as storage
from PIL import Image
import requests
from io import BytesIO

bucket_name = '<my-bucket-name>'
folder = '<name-of-the-directory>'
sample_bucket = storage.Bucket(bucket_name)

for obj in sample_bucket.objects():
    # Check that the object is an image AND that it has the required sub-directory in its name
    if (obj.key[-3:].lower() in ('jpg','png') or obj.key[-4:].lower() in ('jpeg')) and folder in obj.key:
        url='https://storage.googleapis.com/{}/{}'.format(bucket_name, obj.key)
        response = requests.get(url)
        img = Image.open(BytesIO(response.content))
        print("Filename: {}\nFormat: {}\nSize: {}\nMode: {}".format(obj.key, img.format, img.size, img.mode))
        display(img)