Bitmap clip = new Bitmap((int)(8.5 * 72), (int)(11 * 72));
MemoryStream stream = new MemoryStream();
clip.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
byte[] bytes = stream.ToArray();
I ran it on my machine and the bytes.Length
was 8587
, on my fellow developers' machines it was 2009
. Supposedly in .NET
there's no way to influence the quality (or rather the ratio in this case) of the PNG compression. This particular image is a blank one, and I have other tests which work with images with content and they confirm that the compression is lossless (I encountered some debates where that was a question).
But even if the compression is lossless, there's is a tradeoff between the compression algorithm runtime + CPU utilization vs the compression ratio / quality. I wonder how System.Drawing.Imaging
determines the quality, because this above case clearly shows that there can be differences. How can I be sure that on the client's machine it won't choose 100% quality (which would yield a 1.457.337 size file)?
Related material:
Additional info:
I've been chasing exactly this issue, and get exactly the same results as you on two of my machines. I believe I have tracked it down to different versions of System.IO.Compression.DeflateStream on the two machines - png uses deflate as its compression method, and seems to use this class.
When I run the following:
byte[] blank = new byte[1000000];
MemoryStream uncstream = new MemoryStream(blank);
MemoryStream compstream = new MemoryStream();
DeflateStream defstream = new DeflateStream(compstream, CompressionMode.Compress);
uncstream.CopyTo(defstream);
defstream.Close();
byte[] bytes = compstream.ToArray();
System.Console.WriteLine(bytes.Length);
I get 985 bytes on one machine, 8806 bytes on the other.
If I change the constructor to:
DeflateStream defstream = new DeflateStream(compstream, CompressionLevel.Optimal);
I get the same result on the first machine, and an unimplemented exception on the second, indicating that it is using an earlier version of the compression library. When I search for System.IO.Compression.dll on the second machine, I can't find it at all, even though .Net 4 is supposedly installed. I'm guessing that it's hidden somewhere in .Net 2.0. I know that MS claim to have improved DeflateStream between versions 2 and 4 of .Net - see here for a discussion:
http://www.virtualdub.org/blog/pivot/entry.php?id=335
I have also seen it said that the separate compression dll started life in .Net 4.5, although I don't know if this is correct. My next step is to get .Net 4.5 installed on the second machine to see if it makes a difference, but that will have to wait until I'm back in the office in January.