从磁盘读取 png 文件并将其保存回来后文件大小增加
File size increases after reading png file from disk and saving it back
我目前正在开发一个小程序来从磁盘读取 png 文件,进行一些修改并将其保存回来。一切都很顺利运行 除了一个小问题,我把文件存回磁盘后,它的大小总是增加,例如一个27.1MB的文件会变成33.3MB。
经过一些调试,我终于将范围缩小到阅读和保存代码。这是我目前使用的代码:
Bitmap img = new Bitmap(<path to file>);
//omitted
img.Save(<path to new file>, ImageFormat.Png);
我已经验证过无论我是否做任何修改,简单地读取和保存图像都会导致它的大小发生变化。此外,如果我用画图打开保存的文件并从那里保存,文件会缩小回原来的大小。
如何在不改变大小的情况下读取和保存图像?
我认为您缺少 压缩 部分。
像这样添加到您的代码中 -
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);
这里是MSDNlink。希望对你有帮助。
您尝试过 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
除了颜色深度和使用的通道数(w/o alpha)之外,保存的 PNG 文件大小主要取决于两个因素:
- 如何对图像线进行预处理(称为过滤)。
- deflate 算法的压缩级别 (0-9)。
这两个因素会极大地影响输出图像文件的大小。过滤是经验性的,您可以对所有图像行使用四分之一的过滤算法,或者对不同的行使用不同的算法,甚至可以自适应地在各个行上尝试不同的算法并选择最大的压缩率。对于大多数图像作者来说,自适应方式是最耗时且不切实际的。
过滤后,图像数据被deflate压缩。 deflate 算法的压缩级别通常为 0-9,从最低压缩率到最高压缩率。压缩率越高,压缩过程越慢。通常 4 是大多数图像的最佳选择。
过滤过程在 PNG 压缩过程中扮演着非常重要的角色。不同的过滤算法可能导致保存的图像大小差异较大。另一方面,图像大小对压缩级别不太敏感。
您可以使用 TweakPNG 等工具来检查图像包含的颜色深度和通道数。如果原始图像和重新保存的图像具有相同的颜色深度和通道,那么过滤和压缩级别很可能是文件大小增加的罪魁祸首。
事实是,如果编码器没有优化,文件大小往往会增加。但是,如果您不介意 post 处理生成的图像,那么有很多 PNG 优化软件。
我目前正在开发一个小程序来从磁盘读取 png 文件,进行一些修改并将其保存回来。一切都很顺利运行 除了一个小问题,我把文件存回磁盘后,它的大小总是增加,例如一个27.1MB的文件会变成33.3MB。
经过一些调试,我终于将范围缩小到阅读和保存代码。这是我目前使用的代码:
Bitmap img = new Bitmap(<path to file>);
//omitted
img.Save(<path to new file>, ImageFormat.Png);
我已经验证过无论我是否做任何修改,简单地读取和保存图像都会导致它的大小发生变化。此外,如果我用画图打开保存的文件并从那里保存,文件会缩小回原来的大小。
如何在不改变大小的情况下读取和保存图像?
我认为您缺少 压缩 部分。
像这样添加到您的代码中 -
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);
这里是MSDNlink。希望对你有帮助。
您尝试过 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
除了颜色深度和使用的通道数(w/o alpha)之外,保存的 PNG 文件大小主要取决于两个因素:
- 如何对图像线进行预处理(称为过滤)。
- deflate 算法的压缩级别 (0-9)。
这两个因素会极大地影响输出图像文件的大小。过滤是经验性的,您可以对所有图像行使用四分之一的过滤算法,或者对不同的行使用不同的算法,甚至可以自适应地在各个行上尝试不同的算法并选择最大的压缩率。对于大多数图像作者来说,自适应方式是最耗时且不切实际的。
过滤后,图像数据被deflate压缩。 deflate 算法的压缩级别通常为 0-9,从最低压缩率到最高压缩率。压缩率越高,压缩过程越慢。通常 4 是大多数图像的最佳选择。
过滤过程在 PNG 压缩过程中扮演着非常重要的角色。不同的过滤算法可能导致保存的图像大小差异较大。另一方面,图像大小对压缩级别不太敏感。
您可以使用 TweakPNG 等工具来检查图像包含的颜色深度和通道数。如果原始图像和重新保存的图像具有相同的颜色深度和通道,那么过滤和压缩级别很可能是文件大小增加的罪魁祸首。
事实是,如果编码器没有优化,文件大小往往会增加。但是,如果您不介意 post 处理生成的图像,那么有很多 PNG 优化软件。