azure - 尝试修改传入的 WatchableReadStream 对象时,BlockBlobClient.UploadAsync 失败
问题描述
我希望你有一些建议,因为我几乎没有选择。我正在尝试做的事情:
- 通过 azure 门户将图像上传到 blobcontainer
- 这样做时,下面的 blobtrigger 会触发。
- 我想调整作为
Microsoft.Azure.WebJobs.Host.Blobs.WatchableReadStream
对象的传入图像的大小。 - 我想将结果上传到新的 blob 容器。
问题是,当我传递任何其他Stream
的,例如 aMemoryStream
而不是未修改的myBlob
对象时,该UploadAsync
方法似乎默默地失败并BlobTrigger
再次触发,开始一个无限循环。写入当前myBlob
对象也会静默失败。唯一有效的方法是在没有任何修改的情况下传递myBlob
对象,这是无用的。BlockBlobClient.UploadAsync
我正在 Azure 中进行远程调试会话。
此外,当我尝试将MemoryStream
对象提供给该UploadAsync
方法时,也会出现同样的问题。下面的方法是blob触发器:
public async Task UploadImage([BlobTrigger("mediafullsizecontainer/{name}", Connection = "AzureWebJobsStorage")]Stream myBlob, string name, ILogger log)
{
BlockBlobClient fullsizeBlobClient = _mediaFullsizeContainerClient.GetBlockBlobClient(name);
Response<BlobProperties> blobPropertiesResponse = await fullsizeBlobClient.GetPropertiesAsync(null, default);
BlobProperties blobProperties = blobPropertiesResponse.Value;
//Only process blobs when the correct metadata properties are set
if (blobProperties.Metadata.Any(property => property.Key == "category" & property.Value != String.Empty))
{
string category = blobProperties.Metadata["category"];
Stream s = await ResizeImage(myBlob);
BlockBlobClient thumbnailBlobclient = _mediaThumbnailContainerClient.GetBlockBlobClient(name);
Response<BlobContentInfo> uploadResponse = await thumbnailBlobclient.UploadAsync(s, new BlobUploadOptions(), default);
BlobContentInfo blobContentInfo = uploadResponse.Value;
}
}
该ResizeImage
方法使用 SixLabors.ImageSharp 图像处理库。
public async Task<Stream> ResizeImage(Stream inputStream)
{
(Image image, IImageFormat imageFormat) imageWithFormat = await Image.LoadWithFormatAsync(inputStream);
int height = imageWithFormat.image.Height;
int width = imageWithFormat.image.Width;
imageWithFormat.image.Mutate(operation => {
operation.Resize(width / 4, height / 4);
});
MemoryStream outputStream = new MemoryStream();
imageWithFormat.image.Save(outputStream, imageWithFormat.imageFormat);
return outputStream;
}
因此,当我对这样的myBlob
对象进行模拟更改时,myBlob.Write(buffer)
失败:
byte[] buffer = new byte[myBlob.Length];
myBlob.Read(buffer, 0, (int)myBlob.Length);
myBlob.Position = 0;
myBlob.Write(buffer);
当我将myBlob
内容复制到 aMemoryStream
并将 memoryStream 传递给 时UploadAsync
,UploadAsync
失败:
MemoryStream ms = new MemoryStream();
myBlob.CopyTo(ms);
BlockBlobClient thumbnailBlobclient = _mediaThumbnailContainerClient.GetBlockBlobClient(name);
Response<BlobContentInfo> uploadResponse = await thumbnailBlobclient.UploadAsync(ms, new BlobUploadOptions(), default);
唯一有效的是传递myBlob
对象而不进行任何修改,UploadAsync
因为我需要修改传入流:
public async Task UploadImage([BlobTrigger("mediafullsizecontainer/{name}", Connection = "AzureWebJobsStorage")]Stream myBlob, string name, ILogger log)
{
BlockBlobClient fullsizeBlobClient = _mediaFullsizeContainerClient.GetBlockBlobClient(name);
Response<BlobProperties> blobPropertiesResponse = await fullsizeBlobClient.GetPropertiesAsync(null, default);
BlobProperties blobProperties = blobPropertiesResponse.Value;
//Only process blobs when the correct metadata properties are set
if (blobProperties.Metadata.Any(property => property.Key == "category" & property.Value != String.Empty))
{
string category = blobProperties.Metadata["category"];
BlockBlobClient thumbnailBlobclient = _mediaThumbnailContainerClient.GetBlockBlobClient(name);
Response<BlobContentInfo> uploadResponse = await thumbnailBlobclient.UploadAsync(myBlob, new BlobUploadOptions(), default);
BlobContentInfo blobContentInfo = uploadResponse.Value;
}
}
如何将自定义流传递给 UploadAsync 方法?https://docs.microsoft.com/en-us/dotnet/api/azure.storage.blobs.specialized.blockblobclient.uploadasync?view=azure-dotnet上的文档说您只需要一个流对象-但这并不工作。提前致谢。
解决方案
好的,看起来我自己找到了答案,我摆脱了可怕的UploadAsync
方法,并通过outputStream
将调整大小的图像读入缓冲区然后打开一个Stream
用于写入thumbnailBlobclient
对象并将缓冲区传递给流对象来做到这一点。myBlob
尝试修改触发器附带的传入对象,再次触发触发器并创建循环是有道理的。
Stream outputStream = await ResizeAndCropImage(myBlob);
byte[] buffer = new byte[outputStream.Length];
outputStream.Read(buffer);
BlockBlobClient thumbnailBlobclient = _mediaThumbnailContainerClient.GetBlockBlobClient(name);
Stream s = thumbnailBlobclient.OpenWrite(true, new BlockBlobOpenWriteOptions { HttpHeaders = new BlobHttpHeaders { ContentType = "image/jpg" } }, default); //set http headers here as well?
await s.WriteAsync(buffer);
s.Close();
我将以更通用的方式设置内容类型,但这个概念是有效的。
推荐阅读
- sql - 根据 hive 中的 2 列从表中获取最新记录
- search-engine - 想知道是否可以在自定义搜索引擎中使用谷歌图片搜索
- python - 如何杀死正在运行的 Python 脚本?
- properties - Mobx 可观察属性
- java - 给定字符串中的混合重音字符和普通字符在搜索时在 java 中不起作用
- reactjs - React / Symfony:如何开始我的项目?
- javascript - 如何正确设置 Gatsby.js 主页?
- python - 无法在 Jupyter 笔记本(Anaconda)上导入 cv2
- android - 更改可访问性选项时,TextView 自动调整缩减内容
- android - 如何完全禁用软键盘?