有人可以向我解释为什么将PNG图像中的流写回另一个PNG文件会增加最终输出的大小吗?
原始文件:大小(28.6 KB),磁盘大小(32.0 KB)
输出文件:大小(32.1 KB),磁盘大小(36.0 KB)。
执行此操作的代码非常简单:
private void button1_Click(object sender, EventArgs e)
{
var result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
var file = openFileDialog1.FileName;
var stream = new FileStream(file, FileMode.Open);
var newImg = Image.FromStream(stream);
newImg.Save("newPNG.png", ImageFormat.Png);
stream.Close();
}
}
我该如何避免这种情况?我希望最终图像的尺寸与原始图像完全相同。
LE:如果有人想尝试,我上传了原始图片。 cat image
答案 0 :(得分:2)
来自Wikipedia:
有五种可能的过滤器类型可以单独指定 在每条扫描线上以及搜索LZ77的几种可能策略 火柴。因此,存在非常多的不同组合 如何压缩图像。哪种组合最好 压缩取决于各个图像的属性。
也就是说,压缩PNG有很多方法,显然在你的情况下,原始文件的压缩方式与.NET的默认方式不同。我不确定您可以对.NET的输出产生多大影响,但是Image.Save
覆盖了EncoderParameters
。你可能想看一下。 Link
答案 1 :(得分:0)
我敢打赌,因为像GDI +这样的东西会保存不同设置的图像,也可能是不同的编码。
如果您创建新的FileStream
并从第一个读取字节,然后将它们写入第二个,则可以保留相同的大小。因此复制文件。
stream.Position = 0;
using(FileStream fs = new FileStream("newPNG.png"))
{
int totalBytesRead = 0;
while(totalBytesRead < stream.Length)
{
byte[] byteBuffer = new byte[8192];
int bytesRead = stream.Read(readBytes, 0, byteBuffer.Length);
fs.Write(byteBuffer, totalBytesRead, bytesRead);
totalBytesRead += bytesRead;
}
}
stream.Position = 0;
我之前和之后都将stream.Position
设置为零,因为我不知道您将在何处使用此代码。将其设置为零将使FileStream
从文件的开头开始读取。