从磁盘读取png文件并保存后,文件大小增加



我目前正在编写一个小程序,从磁盘读取png文件,做一些修改并保存回来。一切都很顺利,除了一个小问题,我把文件保存回磁盘后,它的大小总是变大,例如,一个27.1MB的文件变成了33.3MB。

经过一些调试后,我最终将其缩小到我的阅读和保存代码。这是我目前使用的代码:

Bitmap img = new Bitmap(<path to file>);
//omitted
img.Save(<path to new file>, ImageFormat.Png);

我已经验证过,无论我做或不做任何修改,简单地读取和保存图像将导致它的大小改变。此外,如果我用Paint打开保存的文件并从那里保存,文件会缩小到原来的大小。

如何读取和保存图像而不改变其大小?

除了颜色深度和使用多少通道(w/o alpha)外,保存的PNG文件大小主要取决于两个因素:

  • 如何对图像线条进行预处理(称为滤波)。
  • deflate算法的压缩级别(0-9)。

这两个因素将极大地影响输出图像文件的大小。滤波是经验性的,你可以对所有图像线使用四种滤波算法中的一种,或者对不同的线使用不同的算法,甚至在单个线上自适应地尝试不同的算法,并选择最大的压缩率。自适应的方式是最耗时和不切实际的大多数图像作家。

过滤后的图像数据被放气压缩。deflate算法的压缩级别通常为0-9,从最低压缩率到最高压缩率。压缩率越高,压缩过程越慢。通常对于大多数图像来说,4是最好的。

过滤过程在PNG压缩过程中起着非常重要的作用,有时是至关重要的。不同的滤波算法可能导致保存的图像大小差异较大。另一方面,图像大小对压缩级别不太敏感。

你可以使用像TweakPNG这样的工具来检查图像包含的颜色深度和通道数量。如果原始图像和重新保存的图像具有相同的颜色深度和通道,那么很可能过滤和压缩级别是增加文件大小的罪魁祸首。

事实是,如果编码器没有优化,通常情况下,文件大小会增加。然而,如果你不介意对生成的图像进行后期处理,有很多PNG优化软件。

你试过玩Endoder吗?ColorDepth字段?PNG也支持透明度,可能会保存一些图像不需要的信息。

ImageCodecInfo pngCodec = ImageCodecInfo.GetImageEncoders().Where(codec => codec.FormatID.Equals(ImageFormat.Png.Guid)).FirstOrDefault();
if (pngCodec != null)
{
    EncoderParameters parameters = new EncoderParameters();
    parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 24); //8, 16, 24, 32 (base on your format)
    image.Save(stream, pngCodec, parameters);
}

附加信息:https://msdn.microsoft.com/en-us/library/system.drawing.imaging.encoder.colordepth(v=vs.110).aspx

我想你错过了压缩部分。
像这样添加到代码中-

Bitmap img = new Bitmap(<path to file>);

这是你错过的-

ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/jpeg");
EncoderParameter myEncoderParameter = new EncoderParameter(Encoder.Quality, 25L);
EncoderParameters myEncoderParameters.Param[0] = myEncoderParameter;

然后保存-

img.Save(<path to file>, myImageCodecInfo, myEncoderParameters);

这是MSDN链接。

最新更新