我正在使用Azure WebJob来调整新上传的图像的大小。调整大小有效,但新创建的图像没有在Blob存储中正确设置其内容类型。相反,他们列出了application / octet-stream。这里是处理调整大小的代码:
{firstname=myname, address={}, phone={mobile2=123, mobile=4532134213131312, office=312321321312312, home=123213213213}, lastname=surname}
我的问题是我在哪里以及如何设置内容类型?这是我必须手动完成的事情,或者我是如何使用库来防止它分配与原始内容类型相同的内容类型(库应该表现出来的行为)?
谢谢!
最终更新
感谢托马斯在达成最终解决方案方面的帮助,这就是它!
public static void ResizeImagesTask(
[BlobTrigger("input/{name}.{ext}")] Stream inputBlob,
string name,
string ext,
IBinder binder)
{
int[] sizes = { 800, 500, 250 };
var inputBytes = inputBlob.CopyToBytes();
foreach (var width in sizes)
{
var input = new MemoryStream(inputBytes);
var output = binder.Bind<Stream>(new BlobAttribute($"output/{name}-w{width}.{ext}", FileAccess.Write));
ResizeImage(input, output, width);
}
}
private static void ResizeImage(Stream input, Stream output, int width)
{
var instructions = new Instructions
{
Width = width,
Mode = FitMode.Carve,
Scale = ScaleMode.Both
};
ImageBuilder.Current.Build(new ImageJob(input, output, instructions));
}
答案 0 :(得分:3)
您无法从实施中设置内容类型:
您需要访问CloudBlockBlob.Properties.ContentType
属性:
CloudBlockBlob blob = new CloudBlockBlob(...);
blob.Properties.ContentType = "image/...";
blob.SetProperties();
Azure Webjob SDK支持Blob绑定,以便您可以直接绑定到blob。
在您的上下文中,您希望绑定到输入blob并创建多个输出blob。
BlobTriggerAttribute
作为输入。BlobTriggerAttribute
绑定到输出blob。因为您想要创建多个输出blob,所以可以直接绑定到输出容器。您触发的功能的代码可能如下所示:
using System.IO;
using System.Web;
using ImageResizer;
using Microsoft.Azure.WebJobs;
using Microsoft.WindowsAzure.Storage.Blob;
public class Functions
{
// output blolb sizes
private static readonly int[] Sizes = {800, 500, 250};
public static void ResizeImage(
[BlobTrigger("input/{name}.{ext}")] Stream blobStream, string name, string ext
, [Blob("output")] CloudBlobContainer container)
{
// Get the mime type to set the content type
var mimeType = MimeMapping.GetMimeMapping($"{name}.{ext}");
foreach (var width in Sizes)
{
// Set the position of the input stream to the beginning.
blobStream.Seek(0, SeekOrigin.Begin);
// Get the output stream
var outputStream = new MemoryStream();
ResizeImage(blobStream, outputStream, width);
// Get the blob reference
var blob = container.GetBlockBlobReference($"{name}-w{width}.{ext}");
// Set the position of the output stream to the beginning.
outputStream.Seek(0, SeekOrigin.Begin);
blob.UploadFromStream(outputStream);
// Update the content type
blob.Properties.ContentType = mimeType;
blob.SetProperties();
}
}
private static void ResizeImage(Stream input, Stream output, int width)
{
var instructions = new Instructions
{
Width = width,
Mode = FitMode.Carve,
Scale = ScaleMode.Both
};
var imageJob = new ImageJob(input, output, instructions);
// Do not dispose the source object
imageJob.DisposeSourceObject = false;
imageJob.Build();
}
}
请注意在DisposeSourceObject
对象上使用ImageJob
,以便我们可以多次读取blob流。
此外,您应该查看有关BlobTrigger
的Webjob文档:How to use Azure blob storage with the WebJobs SDK
WebJobs SDK扫描日志文件以监视新的或更改的blob。这个过程不是实时的;在创建blob后几分钟或更长时间内,函数可能不会被触发。另外,storage logs are created on a "best efforts"基础;无法保证将捕获所有事件。在某些情况下,可能会错过日志。如果blob触发器的速度和可靠性限制对于您的应用程序是不可接受的,建议的方法是在创建blob时创建队列消息,并使用QueueTrigger属性而不是
BlobTrigger
属性处理blob的函数。
因此,从发送文件名的队列中触发消息可能会更好,您可以自动将输入blob绑定到消息队列:
using System.IO;
using System.Web;
using ImageResizer;
using Microsoft.Azure.WebJobs;
using Microsoft.WindowsAzure.Storage.Blob;
public class Functions
{
// output blolb sizes
private static readonly int[] Sizes = { 800, 500, 250 };
public static void ResizeImagesTask1(
[QueueTrigger("newfileuploaded")] string filename,
[Blob("input/{queueTrigger}", FileAccess.Read)] Stream blobStream,
[Blob("output")] CloudBlobContainer container)
{
// Extract the filename and the file extension
var name = Path.GetFileNameWithoutExtension(filename);
var ext = Path.GetExtension(filename);
// Get the mime type to set the content type
var mimeType = MimeMapping.GetMimeMapping(filename);
foreach (var width in Sizes)
{
// Set the position of the input stream to the beginning.
blobStream.Seek(0, SeekOrigin.Begin);
// Get the output stream
var outputStream = new MemoryStream();
ResizeImage(blobStream, outputStream, width);
// Get the blob reference
var blob = container.GetBlockBlobReference($"{name}-w{width}.{ext}");
// Set the position of the output stream to the beginning.
outputStream.Seek(0, SeekOrigin.Begin);
blob.UploadFromStream(outputStream);
// Update the content type => don't know if required
blob.Properties.ContentType = mimeType;
blob.SetProperties();
}
}
private static void ResizeImage(Stream input, Stream output, int width)
{
var instructions = new Instructions
{
Width = width,
Mode = FitMode.Carve,
Scale = ScaleMode.Both
};
var imageJob = new ImageJob(input, output, instructions);
// Do not dispose the source object
imageJob.DisposeSourceObject = false;
imageJob.Build();
}
}