从.NET中的System.Drawing优化PNG输出

Moo*_*Moo 4 .net png system.drawing

我有一个例程,它读取图像,调整大小并将其定位在新背景上(全新的位图,只是设置了大小).

这一切都非常完美,但是现在我想减小它输出的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();
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*ght 8

超级用户答案,如何在没有Fireworks的情况下阅读Fireworks PNG多层文件,解释说Fireworks具有PNG扩展,可以在PNG文件中存储多个图层.展平会移除多余的图层.鉴于文件不是首先在Fireworks中创建的,理论上"扁平化"应该对它们没有影响.我怀疑尺寸减小是由于Firework的保存 - 优化PNG文件.

我用于PNG优化的工具是:

  1. 转换为PNG8:如果颜色很少(比如屏幕截图),那么我使用pngnqGIMP的索引颜色模式来量化低至256色.PNG8可以小于PNG24或PNG32.有关详细信息,请参阅PNG8 - 明确的获胜者.
  2. Optipng,一种快速通用的PNG优化器.C#PNG优化教程详细介绍了如何从C#运行optipng.
  3. 最后,pngout很慢,但通常(80-90%的时间)设法将PNG压缩得比optipng更低.首先运行optipng,因为optipng会自动执行pngout不会尝试的其他优化.

如果您对优化PNG文件感兴趣,那么PNG规范非常简单,值得一看最小的透明PNG.与规范一样,实现也非常简单,例如,单个文件,纯Python实现png.py(pypng).