【问题标题】:How to copy image via drawImage如何通过drawImage复制图像
【发布时间】:2012-10-19 22:59:21
【问题描述】:

我需要在我的磁盘上制作一个 PNG 图像的副本。事实上我需要更复杂的思考,但这是其中的一部分。 所以,

我正在这样做:

Bitmap oldbmp = new Bitmap( filename );

Bitmap newbmp = new Bitmap(oldbmp.Size.Width, oldbmp.Size.Height, oldbmp.PixelFormat);

// if I don't do this, destination image looks bigger and clipped
newbmp1.SetResolution(oldbmp.HorizontalResolution, oldbmp.VerticalResolution);

Graphics graphics = Graphics.FromImage(newbmp);
graphics.DrawImageUnscaled(oldbmp,0,0);

newbmp.Save( filename2 );

我所拥有的是第二个文件具有不同的文件大小(有时比第一个更大,有时小于第一个)。

我猜编码有问题,但无法理解到底是什么。我必须更改或添加什么?

附: Bitmap.Clone( ... ) 不能满足我的需要。

更新:

好吧,我的实际任务是:

  1. 将文件剪切成几个较小的部分。

  2. 将部件保存到磁盘。

  3. 从磁盘读取部分。

  4. 将零件组装回完整图像。

  5. 将完整图像保存到磁盘。

第一个文件是 PNG,最后一个文件是 PNG,如果部分未更改,它们必须具有相同的大小。

不同的大小很重要,因为有些文件非常大,差异可能超过 2 MB!

更新2:

第一张图片。执行代码后文件的大小变大了。

【问题讨论】:

  • 您需要复制还是更改?如果您只是想要一份副本,请使用File.Copy ...
  • 您的问题不清楚您要更改磁盘文件并保存吗?否则正如@driis 所说,使用'File.Copy'
  • 我猜想更改然后从问题中保存,但首先保存并测试以验证保存是否正常工作,问题是由于文件大小不同,测试“失败”。我认为文件大小不同并不重要,只要结果是打开时看起来相同的有效 png。
  • PNG 使用无损压缩,即使尺寸和位深相同,如果图像不同,它也不保证文件大小相同。
  • filename2 是 PNG 图像吗?我不是说它是文件扩展名,在文本编辑器中打开它并检查文件顶部的“PNG”。是不是看起来一模一样

标签: c# image bitmap


【解决方案1】:

我认为这是由于缺乏对 .Net PNG 编码器的控制。您可以通过在结果文件上再次运行拆分组合来确认这一点,在我的测试中,文件大小第二次保持不变,我做的第二次测试是使用 Paint.Net 加载/保存,并且在我自己的代码中没有拆分/combining 这也增加了文件大小。我在仓促构建的拆分器/合并器中注意到的另一件事是,如果拆分的数量不是图像宽度的一个因素,那么由于舍入错误导致结果文件略有不同,这当然会影响文件大小。

我认为要获得相同的文件大小,您唯一能做的就是使用最初构建文件时使用的相同编码器。根据您制作图像的方式,这可能是可能的,但您很可能会被这种增加所困扰。

注意:使用上面的测试文件(最初是 103,191 字节)我的结果是 121,715 字节

【讨论】:

  • 是的,Paint.Net 使这个文件比我的代码更大。我认为有一些控制编码参数的可能性,但如果不是......可悲的是(
  • @АндрейСелянин see here
【解决方案2】:
        Bitmap source = new Bitmap("input.png");

        Rectangle rec = new Rectangle(0, 0, 80, 144);


        Bitmap[] parts = new Bitmap[10];

        for (int i = 0; i < 10; i++)
        {
            rec.Y = 144 * i;

            Bitmap b = (Bitmap)cropImage(source, rec);

            b.Save(String.Format("{0}.png", i), ImageFormat.Png);
            parts[i] = b;
        }

        Bitmap output = new Bitmap(source.Width, source.Height);
        Graphics g = Graphics.FromImage(output);

        for(int i=0; i<10; i++)
        {
            Bitmap b = parts[i];

            g.DrawImageUnscaled(b, new Point(0, i * 144));
        }

        output.MakeTransparent(Color.Transparent); // test if the image view don't changes, use this to reduce the overhead, in my test it reduced output size by 10 percent without changing the view

        output.Save("output.png", ImageFormat.Png);

【讨论】:

  • 那么您遇到的问题是什么?
  • 如果我只是剪切和组装一个文件,该文件可以有另一个文件大小。只是看起来不对。
  • 你的文件是 101 KB,10 部分加起来是 118 KB,输出也是 118 KB,使用 MakeTransparent 输出变成 110 KB。开销是在裁剪和保存期间产生的
猜你喜欢
  • 2015-08-09
  • 2014-07-28
  • 1970-01-01
  • 2017-08-14
  • 1970-01-01
  • 1970-01-01
  • 2013-07-25
  • 2019-08-28
  • 2014-07-06
相关资源
最近更新 更多