2010-01-15 74 views
4

我有一個例程,讀取圖像,調整它的大小,並將其放置在新的背景(全新的位圖,只是大小設置)。從.NET中的System.Drawing優化PNG輸出

這一切工作萬無一失了,但我現在想減少PNG文件它輸出的大小 - 如果我輸出JPEG文件,我得到了〜4K左右的文件大小我希望,但我的PNG文件更大小超過30K。

我知道我永遠不會使用PNG獲得JPEG級別,但我認爲我可以做得更好一點。

當我將輸出的PNG加載到Fireworks中時,我注意到背景和調整大小的圖像仍然是單獨的圖層。在Fireworks中壓扁PNG可將文件大小減少5到10K。

那麼,首先有辦法以編程方式將輸出PNG平坦化?其次,還有什麼人可以推薦減少PNG大小嗎?

我使用的是PNG文件,因爲我希望保留背景爲透明。

代碼:

private static void ResizeImage(String ImageInPath, int MaxWidth, int MaxHeight, String ImageOutPath, Boolean PadImage, Color MyColour) 
{ 
    Bitmap MyImage = new Bitmap(ImageInPath); 
    Bitmap MyResizedImage = null; 

    int XPosition = 0; 
    int YPosition = 0; 
    float Ratio = MyImage.Width/(float)MyImage.Height; 

    int MyImageHeight = MyImage.Height; 
    int MyImageWidth = MyImage.Width; 

    if (MyImage.Width > MyImage.Height) 
    { 
     if (MyImage.Width > MaxWidth) 
      MyResizedImage = new Bitmap(MyImage, new Size(MaxWidth, (int)Math.Round(MaxWidth/
      Ratio, 0))); 
     YPosition = (MaxHeight/2) - (MyResizedImage.Height/2); 
    } 
    else if (MyImage.Height > MyImage.Width) 
    { 
     if (MyImage.Height > MaxHeight) 
      MyResizedImage = new Bitmap(MyImage, new Size((int)Math.Round(MaxWidth * Ratio, 
      0), MaxHeight)); 
     XPosition = (MaxWidth/2) - (MyResizedImage.Width/2); 
    } 


    if (PadImage) 
    { 
     Bitmap MyUnderlay = new Bitmap(MaxWidth, MaxHeight); 
     var Canvas = Graphics.FromImage(MyUnderlay); 
     Canvas.Clear(MyColour); 
     Canvas.InterpolationMode = InterpolationMode.HighQualityBicubic; 
     Canvas.DrawImage(MyResizedImage, XPosition, YPosition); 
     Canvas.Save(); 
     if (MyColour == Color.Transparent) 
     { 
      MyUnderlay.Save(ImageOutPath + ".png", ImageFormat.Png); 
     } 
     else 
     { 
      MyUnderlay.Save(ImageOutPath, ImageFormat.Jpeg); 
     } 

     Canvas.Dispose(); 
     MyUnderlay.Dispose(); 
    } 
    else 
    { 
     MyResizedImage.Save(ImageOutPath, ImageFormat.Jpeg); 
    } 

    MyResizedImage.Dispose(); 
    MyImage.Dispose(); 
} 

回答

7

超級用戶答案,How to read Fireworks PNG multilayer files without Fireworks解釋說,煙花具有PNG擴展存儲多個圖層的PNG文件。展平會移除額外的圖層。鑑於這些文件不是在Fireworks中創建的,理論上「扁平化」應該對它們沒有影響。我懷疑減小的大小是由於Firework的保存 - 優化PNG文件。

我使用PNG優化的工具有:

  1. 轉換爲PNG8:如果有幾種顏色(比如截圖)然後我用pngnqGIMP's索引顏色模式向下量化到256個色。 PNG8可以小於PNG24或PNG32。詳情請參閱PNG8 – The Clear Winner
  2. Optipng,一個快速的通用PNG優化器。 C# PNG Optimization Tutorial有關於如何從C#運行optipng的詳細信息。
  3. 最後,pngout很慢,但通常(80-90%的時間)管理擠壓PNG比optipng更進一步。儘管先運行optipng,但optipng會自動執行pngout不會嘗試的其他優化。

如果您有興趣優化PNG文件,PNG specification是令人驚訝的直截了當,值得看看Smallest possible transparent PNG。像規範一樣,實現也非常簡單,例如,單個文件,純粹的Python實現png.py (pypng)

+0

關於煙花及其擴展 - 巴新是由.NET Framework從一個全新的位圖和JPEG格式創建的,但是當加載到Fireworks我仍然可以操縱既可作爲單獨的對象,直到我壓扁從煙花出口的一切,所以在這裏比Fireworks擴展更多,或者.Net支持它們... – Moo 2010-01-16 11:23:11

+0

Moo,可以將貼圖位圖和jpg文件的代碼貼出來嗎? 我原以爲在將jpg和位圖都繪製到另一個位圖之後,任何「圖層」信息就會消失很久,並且生成的png將會是這兩者的組合。這不是這種情況嗎? – 2010-01-16 20:31:40

+0

喬納森,我已經添加了代碼:) – Moo 2010-01-17 09:53:18