利用Magick.NET來進行圖片的重新採樣與無損壓縮

最近因為工作的關係,研究了一下Magick.NET相關的程式碼,發現與GDI+(System.Drawing)比較起來,程式碼簡直簡單到爆,雖然到最後還是放棄採用,不過還是在此把研究結果記錄在此,以備不時之需。

Step 1. 先用nuget下載到現在最新的Magick.NET版本,Magick.NET其實有分成很多版本,一般來說網頁適用Q8版本(8 Bits)即可,在這裡我為了追求最大相容性,因此下載了x86、x64混合版本(AnyCPU)。

nuget Magick.Net-Q8-AnyCPU

Step 2. 程式碼超級簡單,不解釋。

using (ImageMagick.MagickImage oImage = new ImageMagick.MagickImage("original.jpg"))
{
  oImage.Format = ImageMagick.MagickFormat.Pjpeg;   //漸進式JPEG
  oImage.ColorSpace = ImageMagick.ColorSpace.sRGB;  //色盤採用sRGB
  oImage.Quality = 85;    //JPEG壓縮率
  oImage.Resize(500, 0);  //如果不需要重新指定Size可以不必寫這行,0代表依比例運算垂直高度
  oImage.Write("target.jpg");
}

優點:

缺點:

  1. 相較GDI+同樣的壓縮比例(當然大家自己的定義不同啦),壓出來的檔案肥大很多,丟到tinyPNG.com就知道效果,隨便一壓縮都是接近40%起跳。(※註:tinyPNG並非無損壓縮,只是他用特別的演算法讓圖片大小可以縮減,又讓你的視覺看不出來特別的差異。)
  2. 產生的圖形檔丟到Google PageSpeed Insights,會被嚴重的嫌棄圖形檔太大。(話說現在Google為最佳化網頁推行有損壓縮,我不知道到底在想甚麼,建議壓縮後的JPG檔案畫質跟屎一樣!)
  3. 若要使用需要外掛DLL,相較GDI+內建,部署上仍然有些不便。

結論

壓縮與品質本來就是天秤的兩端,其實最後放棄採用的原因就是被Google嚴重嫌棄,這代表現階段Magick.NET仍然有很大的調整空間(諷刺的是PageSpeed Insights推薦的影像壓縮工具ImageMagick,竟然是Magick.NET的母產品啊!)在這邊仍然要幫Magick.NET講一句話,就是Google嫌棄的太無道理,假設PageSpeed Insights建議你這張壓縮後的圖片仍然可以減少32%的檔案大小量,當你真的去打開那張建議的JPG檔案觀看後,你就會吐血了。

若你真的要進行Magick.NET的解決方案,建議搭配「jpegtran.exe」這支EXE檔案一起運作,藉由Huffman table的最佳化,可以為你的檔案進一步的壓縮檔案大小。不過,你必須呼叫外部執行檔,這點得要小心斟酌了。

下面列出「jpegtran.exe」壓縮指令與呼叫外部執行檔案方法,幫大家減少一些survey時間。

jpegtran.exe -copy none -optimize -progressive -outfile target.jpg original.jpg
private void optimizeJPEG(string file)
{
  string pathToExe = HostingEnvironment.MapPath("~\") + "jpegtran.exe";

  var proc = new Process
  {
    StartInfo =
    {
      Arguments = "自己參考上面的引數去設計",
      FileName = pathToExe,
      UseShellExecute = false,
      CreateNoWindow = false,
      WindowStyle = ProcessWindowStyle.Hidden,
      RedirectStandardError = true,
      RedirectStandardOutput = true
    }
  };

  Process jpegTranProcess = proc;

  jpegTranProcess.Start();
  jpegTranProcess.WaitForExit();
}
System.Drawing GDI+ JpegTran LossyCompression LosslessCompression