【问题标题】:Writing the stream of a png back into another png increases the size. Why?将 png 的流写回另一个 png 会增加大小。为什么?
【发布时间】:2016-08-07 13:51:23
【问题描述】:

有人可以向我解释为什么将 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

【问题讨论】:

标签: c# .net image png


【解决方案1】:

来自Wikipedia

有五种可能的过滤器类型可以单独指定 在每条扫描线上和几种可能的搜索 LZ77 的策略 火柴。因此,有大量不同的组合 了解如何压缩图像。哪种组合效果最好 压缩将取决于单个图像的属性。

也就是说,有很多方法可以压缩 PNG,显然在您的情况下,原始文件的压缩方式与 .NET 的默认方式不同。我不确定你能在多大程度上影响 .NET 的输出,但有一个覆盖 Image.Save 需要 EncoderParameters。你可能想看看那个。 Link.

【讨论】:

  • 我相信这是正确的。通过复制副本来证明它。如果第一个副本的大小发生变化,但随后没有发生变化,则压缩是罪魁祸首。不幸的是,.NET 让您几乎无法控制 PNG 文件中的压缩级别。
【解决方案2】:

我敢打赌,因为像 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 从文件开头开始读取。

【讨论】:

    猜你喜欢
    • 2013-05-29
    • 1970-01-01
    • 2010-12-02
    • 2017-04-22
    • 2014-10-17
    • 2012-11-19
    • 2012-08-26
    • 1970-01-01
    • 2012-11-22
    相关资源
    最近更新 更多