最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Why is flipping a PNG changing the quality of the image? - Stack Overflow

programmeradmin3浏览0评论

I have the following code:

System.Drawing.Image img1 = System.Drawing.Image.FromFile(imgPath);
System.Drawing.Image img2 = System.Drawing.Image.FromFile(imgPath);
img2.RotateFlip(RotateFlipType.RotateNoneFlipX);

var codec = ImageCodecInfo.GetImageEncoders().First(x => x.CodecName.Contains("Built-in PNG Codec"));
EncoderParameters ep = new EncoderParameters();
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100);

img1.Save(@"C:\test1.png", codec, ep);
img2.Save(@"C:\test2.png", codec, ep);

I was expecting one PNG to be the mirror image of the other - but it is not. The pixels of test2.png are not the mirror image of test1.png (i.e. test2.png is lower quality).

pixel2 is instead smaller and "fuzzier" than the original, which I would consider "loss of quality".

How can I flip the png without such loss of quality?

I have the following code:

System.Drawing.Image img1 = System.Drawing.Image.FromFile(imgPath);
System.Drawing.Image img2 = System.Drawing.Image.FromFile(imgPath);
img2.RotateFlip(RotateFlipType.RotateNoneFlipX);

var codec = ImageCodecInfo.GetImageEncoders().First(x => x.CodecName.Contains("Built-in PNG Codec"));
EncoderParameters ep = new EncoderParameters();
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100);

img1.Save(@"C:\test1.png", codec, ep);
img2.Save(@"C:\test2.png", codec, ep);

I was expecting one PNG to be the mirror image of the other - but it is not. The pixels of test2.png are not the mirror image of test1.png (i.e. test2.png is lower quality).

pixel2 is instead smaller and "fuzzier" than the original, which I would consider "loss of quality".

How can I flip the png without such loss of quality?

Share Improve this question edited Mar 17 at 22:53 mjwills 24k6 gold badges44 silver badges70 bronze badges asked Mar 14 at 15:12 user107586user107586 819 bronze badges 8
  • 1 PNG uses lossless compression (unlike JPEG). So there will be no loss of quality despite the compression. – Olivier Jacot-Descombes Commented Mar 14 at 16:10
  • @OlivierJacot-Descombes, I don't know what you consider "no loss of quality" because the resulting image is smaller and "fuzzier" than the original, which I would consider "loss of quality". – user107586 Commented Mar 14 at 17:16
  • If you apply physical rotation of the pixels, no chance. You could find a way to modify the EXIF PropertyItem that relates to the Rotation of the image, and a viewer software may interpret it correctly (as the softwares of cell phones do), so it presents the image rotated. Requires a PNG 1.2 compatible encoder, so you can fet about the System.Drawing one – Jimi Commented Mar 14 at 17:49
  • 1 You already asked a similar question; I can recognize it by familiar img1.Save(@"C:\test1.png", codec, ep) and RotateFlip. Your questions look like you are trying to solve an XY Problem. I don't think you ever need uncompressed image files; they are possible, but the practical idea is nearly absurd. You need to learn the concept of lossless compression. – Sergey A Kryukov Commented Mar 15 at 2:28
  • 1 I have altered the question to make the actual problem clearer. I am not convinced the problem is actually occurring, but we can't tell that until you provide us in the input image to test it. – mjwills Commented Mar 17 at 22:57
 |  Show 3 more comments

2 Answers 2

Reset to default 0

I changed your code slightly:

Image img1 = Image.FromFile(imgPath);
Image img2 = Image.FromFile(imgPath);
img2.RotateFlip(RotateFlipType.RotateNoneFlipX);

string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

img1.Save(Path.Combine(desktop, "test1.png"), ImageFormat.Png);
img2.Save(Path.Combine(desktop, "test2.png"), ImageFormat.Png);

Then I applied it to an image, loaded the mirrored image (test2.png) into a graphics application and mirrored it again there to undo the mirroring. Now I subtracted the original image from this de-mirrored image. The result was black image. I.e., no differences can be seen.


PNG uses the DEFLATE algorithm to produce a lossless data compression file format.

How this algorithm works, is explained in the linked article. Here a very simplified explanation: Imagine an image contains 20 pixels in a row having the same color. Instead of saving 20 pixels, one pixel is saved along with the number 20. When the image is loaded, the 20 pixels can be restored with no loss of quality.

Therefore, you can not compare image qualities by comparing their file sizes.

Something else is going on in your case.


What can cause a mirrored image to look blurred is Microsoft ClearType.

ClearType is a software technology developed by Microsoft that improves the readability of text on existing LCDs (Liquid Crystal Displays), such as laptop screens, Pocket PC screens, and flat panel monitors. With ClearType font technology, the words on your computer screen look almost as sharp and clear as those printed on a piece of paper.

ClearType works by accessing the individual vertical color stripe elements in every pixel of an LCD screen.

If you take a screenshot of a text on a LCD screen and zoom in, you will see colored borders around the edges of the characters. The colors a balanced in such a way that you will not notice them on a LCD screen (on the original-sized image). Instead the text will appear sharper.

For this to work, the order of the Reg, Green, and Blue components of a pixel on the LCD must be respected. But if you mirror the image, this does not work and the text will look blurred and have colored edges.

I cannot reproduce this problem on my screen, but it might depend on the exact LCD type.

This will get the raw bytes from memory, no compression.

You can read more on PixelFormat

public static byte[] GetImageAsRawBytes(System.Drawing.Bitmap pngBitmap)
        {
            var pngRectangle = new System.Drawing.Rectangle(0, 0, pngBitmap.Width, pngBitmap.Height);
            var pngData = pngBitmap.LockBits(pngRectangle, System.Drawing.Imaging.ImageLockMode.ReadOnly, pngBitmap.PixelFormat);
            var result = new byte[pngData.Height * pngData.Stride];
            System.Runtime.InteropServices.Marshal.Copy(pngData.Scan0, result, 0, result.Length);
            pngBitmap.UnlockBits(pngData);
            return result;
        }
发布评论

评论列表(0)

  1. 暂无评论