0

I need to make a copy of an PNG image on my disk. In fact I need more complicated think, but this is a part of it. So,

I'm doing this:

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 );

What I have is the second file has different filesize (sometimes more, sometimes less then the first one).

I guess something wrong with encoding, but cannot understand what exactly. What must I change or add?

P.S. Bitmap.Clone( ... ) doesn't do what I need.

Update:

Ok, my actual task is:

  1. Cut file to several smaller parts.

  2. Save parts to disk.

  3. Read parts from disk.

  4. Assemble parts back to full image.

  5. Save full image to disk.

First file is PNG, last file is PNG, they must be of equall size if parts haven't been changed.

Different size matters, because some files a really large and difference can be more than 2 MBs!

UPDATE2:

The first image. After executing the code the size of file grows.

The first image

  • Do you need to copy or to change it ? If you just want a copy, use `File.Copy` ... – driis Oct 19 '12 at 13:07
  • Your question is unclear do you want to alter the file your disk and save it ? otherwise as @driis said use 'File.Copy' – Mohsen Afshin Oct 19 '12 at 13:09
  • I would guess change then save from the question but first save and test to verify the save is working correctly, with the problem being the test is "failing" on account of the file size being different. I don't think it really matters that the file size is different as long the result is a valid png which looks the same when opened. – James Oct 19 '12 at 13:11
  • PNG uses lossless compression, it does not guarantee the same file size if the image is different, even though dimensions and bit depth are the same. – driis Oct 19 '12 at 13:12
  • Is filename2 a PNG image?, I don't mean it's file extension, open it in a text editor and check for "PNG" at the top of the file. Does it look **Exactly** the same. – James Oct 19 '12 at 13:23
  • Yes, it's PNG. The first 4 bytes are ‰PNG – Андрей Селянин Oct 19 '12 at 13:27
  • Could you upload your test image to allow the same problem to be replicated? – James Oct 19 '12 at 13:42

2 Answers2

0
        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);
Mohsen Afshin
  • 13,273
  • 10
  • 65
  • 90
0

I think this is due to a lack of control over the .Net PNG Encoder. You can confirm this by running the split combine again on the result file and in my test the file size stayed the same the second time, The second test I did was a load/save using Paint.Net and in my own code without the splitting/combining and this also increased the filesize. The other thing I noticed in my hastily constructed splitter/combiner was a subtly different file at the result due to rounding errors if the number of splits wasn't a factor of the width of the image, which of course affects the filesize.

I think the only thing you can do to get the same file size is to use the same encoder the file was originally constructed with. Depending on how you produce the images this might be possible, but more than likely you're stuck with this increase.

Note: using the test file above (originally 103,191 bytes) my result was 121,715 bytes

James
  • 9,774
  • 5
  • 34
  • 58
  • Yes, Paint.Net makes this file even bigger than my code does. I thougth there was some posibility to control encoding params, but if it wasn't... Sadly ( – Андрей Селянин Oct 19 '12 at 14:48
  • @АндрейСелянин [see here](http://stackoverflow.com/questions/4418454/c-seeking-png-compression-algorithm-library#4520842) – James Oct 19 '12 at 15:00