Azure blob:图像优化

问题描述 投票:0回答:1

需要优化上传到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)

感谢您的建议以解决此问题。

c# .net azure azure-storage azure-functions
1个回答
0
投票

您将需要使用某些描述的文件系统,或者如果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}");      
   }
}
© www.soinside.com 2019 - 2024. All rights reserved.