【问题标题】:Read Azure Storage blob into matplotlib将 Azure 存储 blob 读入 matplotlib
【发布时间】:2021-02-28 00:47:26
【问题描述】:

我正在 Azure Functions 环境中使用 matplotlib.pyplot 和 Azure 存储 blob (azure.storage.blob)(不应访问文件系统)。

我的目标是获得一个 blob:

service = blob.BlobServiceClient(account_url="https://mysa.blob.core.windows.net", credential=SA_PRIMARY_KEY)
blob_client = service.get_blob_client(container="mycontainer", blob="myimg.JPG")
blob_data = blob_client.download_blob()

并使用imread 使用pyplot 打开它,例如:

img = plt.imread(blob_data_to_read_opened_stream, format="JPG")

所以我想我错过了一块。获得blob_data 对象后,需要将其内容复制到流中,并将其传递给pyplot

with open("./BlockDestination.jpg", "wb") as blob_stream:
    blob_data = blob.download_blob()
    blob_data.readinto(blob_stream)
    img = plt.imread(blob_stream, format="JPG")

这会失败,因为 imread 需要一个

以读取二进制模式打开的类文件对象

如何在不打开两个不同的流的情况下实现我的目标?

【问题讨论】:

    标签: python matplotlib azure-functions azure-storage


    【解决方案1】:

    您可以生成SAS token 并使用它直接从您的存储帐户读取图像,而不是下载图像并读取它们。它将减轻服务器压力,并且这里只有一个读取流。试试下面的代码:

    from azure.storage.blob import ResourceTypes, AccountSasPermissions, generate_account_sas,BlobServiceClient
    from datetime import datetime, timedelta
    import matplotlib.pyplot as plt
    import matplotlib.patches as patches
    import matplotlib.cbook as cbook
    
    connStr = '<storage account connection string>'
    containerName ='<container name>'
    blobName = "<image name>"
    
    blob_service_client = BlobServiceClient.from_connection_string(connStr)
    
    sas_token = generate_account_sas(
        blob_service_client.account_name,
        account_key=blob_service_client.credential.account_key,
        resource_types=ResourceTypes(object=True),
        permission=AccountSasPermissions(read=True),
        expiry=datetime.utcnow() + timedelta(hours=1)
    )
    
    destImageUrl = blob_service_client.primary_endpoint + containerName + "/" + blobName + "?" + sas_token
    
    image  = plt.imread(destImageUrl , format="JPG")
    
    fig, ax = plt.subplots()
    im = ax.imshow(image)
    patch = patches.Circle((260, 200), radius=200, transform=ax.transData)
    im.set_clip_path(patch)
    
    ax.axis('off')
    plt.show()
    

    我的 .jpg 文件内容:

    结果:

    【讨论】:

    • 一目了然!只是要确定。在另一种情况下,我会处理两个不同的流。对吗?
    猜你喜欢
    • 2019-12-24
    • 2023-01-03
    • 2018-04-13
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 2012-06-16
    • 1970-01-01
    • 2019-07-18
    相关资源
    最近更新 更多