需要优化上传到azure blob存储的图像。我正在编写一个天蓝色的功能应用程序(blob触发器),它将获取上传的图像并使用图像压缩器库对其进行压缩,然后将生成的图像保存到另一个blob中。
我已经创建了一个自定义库来通过引用ImageOptimizerWebJob库来压缩图像。压缩逻辑运行适当的图像压缩器exe文件(pingo.exe,cjpeg.exe,jpegtran.exe或gifsicle.exe)来压缩给定的图像。
public CompressionResult CompressFile(string fileName, bool lossy)
{
string targetFile = Path.ChangeExtension(Path.GetTempFileName(), Path.GetExtension(fileName));
ProcessStartInfo start = new ProcessStartInfo("cmd")
{
WindowStyle = ProcessWindowStyle.Hidden,
WorkingDirectory = _cwd,
Arguments = GetArguments(fileName, targetFile, lossy),
UseShellExecute = false,
CreateNoWindow = true,
};
var stopwatch = Stopwatch.StartNew();
using (var process = Process.Start(start))
{
process.WaitForExit();
}
stopwatch.Stop();
return new CompressionResult(fileName, targetFile, stopwatch.Elapsed);
}
private static string GetArguments(string sourceFile, string targetFile, bool lossy)
{
if (!Uri.IsWellFormedUriString(sourceFile, UriKind.RelativeOrAbsolute) && !File.Exists(sourceFile))
return null;
string ext;
try
{
ext = Path.GetExtension(sourceFile).ToLowerInvariant();
}
catch (ArgumentException ex)
{
Console.WriteLine(ex);
return null;
}
switch (ext)
{
case ".png":
File.Copy(sourceFile, targetFile);
if (lossy)
return string.Format(CultureInfo.CurrentCulture, "/c pingo -s8 -q -palette=79 \"{0}\"", targetFile);
else
return string.Format(CultureInfo.CurrentCulture, "/c pingo -s8 -q \"{0}\"", targetFile);
case ".jpg":
case ".jpeg":
if (lossy)
{
return string.Format(CultureInfo.CurrentCulture, "/c cjpeg -quality 80,60 -dct float -smooth 5 -outfile \"{1}\" \"{0}\"", sourceFile, targetFile);
}
return string.Format(CultureInfo.CurrentCulture, "/c jpegtran -copy none -optimize -progressive -outfile \"{1}\" \"{0}\"", sourceFile, targetFile);
case ".gif":
return string.Format(CultureInfo.CurrentCulture, "/c gifsicle -O3 --batch --colors=256 \"{0}\" --output=\"{1}\"", sourceFile, targetFile);
}
return null;
}
我的azure函数使用这个库来完成这项工作。但这里的挑战是,输入和输出文件位置是azure blobs而不是本地桌面路径。
输入和输出blob数据来自Run()方法
public static void Run([BlobTrigger("test/{name}", Connection = "")]Stream myBlob,
[Blob("test-output/{name}", FileAccess.ReadWrite)]CloudBlockBlob output,
string name,
TraceWriter log)
但我不能直接使用图像压缩器的输入和输出blob路径。我无法找到一种方法将输出图像作为内存流(上传到输出blob)
感谢您的建议以解决此问题。
您将需要使用某些描述的文件系统,或者如果exe提供StdIn / Out,您可以在MemoryStream
中执行此操作并保存(使用它)您喜欢的方式
以下是支持StdIn / Out的jpegoptim.exe
的示例
var startInfo = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = @"jpegoptim.exe",
Arguments = @"-s --stdin --stdout",
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
UseShellExecute = false,
CreateNoWindow = true
};
using (var process = Process.Start(startInfo))
{
inputStream.CopyTo(process.StandardInput.BaseStream);
process.StandardInput.Close();
using (var file = new FileStream(dest, FileMode.Create, FileAccess.Write))
{
process.StandardOutput.BaseStream.CopyTo(file);
}
if (process.ExitCode != 0)
{
var message = process.StandardError.ReadToEnd();
throw new InvalidOperationException($"Failed to optimise image : {message}");
}
}