我试图创建C#Azure WebJob,它是在新的Blob创建时触发的,用于将上传的图像调整为三种不同的大小。我找到并关注了这个伟大的tutorial。
有两个部分,第一部分"工作"但是进入一个递归循环,因为三个新尺寸的创建触发了脚本,这为三个新图像中的每一个创建了三个实例,依此类推。这是故意的,强调最终实施的必要性。
这是"工作的初始递归循环代码"在functions.cs文件中的位置:
public static void ResizeImagesW800([BlobTrigger("input/{name}.{ext}")] Stream input,
[Blob("output/{name}-w800.{ext}", FileAccess.Write)] Stream output)
{
ResizeImage(input, output, 800);
}
public static void ResizeImagesW500([BlobTrigger("input/{name}.{ext}")] Stream input,
[Blob("output/{name}-w500.{ext}", FileAccess.Write)] Stream output)
{
ResizeImage(input, output, 500);
}
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));
}
以下是Visual Studio 2015发出错误的代码:
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));
}
此行引发错误:
var inputBytes = inputBlob.CopyToBytes();
错误是:
CS1061: 'Stream' does not contain a definition for 'CopyToBytes' and no extension method 'CopyToBytes' accepting a first argument of type 'Stream' could be found (are you missing a using directive or an assembly reference?)
我尝试使用.NET 3.5,4.0,4.5,4.5.1,4.5.2,4.6,4.6.1作为目标框架,但所有这些都会产生同样的错误。
此外,这里是Functions.cs文件的using语句:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.WindowsAzure.Storage;
using ImageResizer;
我在这里做错了什么?谢谢!
更新1
using System;
using System.Collections.Generic;
using System.IO;
using System.Web;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.WindowsAzure.Storage;
using ImageResizer;
using ImageResizer.ExtensionMethods;
using Microsoft.WindowsAzure.Storage.Blob;
namespace HilcoIndustrialAssetApiWebJob
{
public class Functions
{
// output blolb sizes
private static readonly int[] Sizes = { 800, 500, 250 };
public static void ResizeImagesTask(
[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);
Console.WriteLine("New Blob name -> " + name);
// 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}_{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();
}
}
}
答案 0 :(得分:2)
我猜这个示例使用的是ImageResizer NuGet包。 您可以使用该命令从VS2015安装它 安装包ImageResizer。 然后,如果你添加 使用ImageResizer.ExtensionMethods; 在您的代码中,您将获得扩展Stream对象的CopyToBytes方法。 希望这可以帮助 最好的祝福 斯特凡
答案 1 :(得分:0)
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();
}
}
答案 2 :(得分:0)
我用VS2015创建了一个Webjob项目(仍然在update1中),我正在使用Azure 2.8 SDK(我很快会将其更新为2.9)。
我做过切割&amp;粘贴原始链接中的示例代码。 我添加了两个app config连接字符串(并在Application Settings中更新了Web App对应的连接字符串)。 我有juste添加了引用的nugget包和缺少的“using”。 它工作正常。
我已经在GitHub上发布了示例代码,以备您尝试使用。
https://github.com/stephgou/ImageResizer.git
您只需更新应用配置和您的网络应用连接字符串。
希望这有帮助
祝你好运 斯特凡