Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Image.Save occasionally generates a PNG with a bad IDAT chunk

Tags:

I have a C#/.NET utility I wrote that loads PNG images from disk

Bitmap b = Bitmap.FromStream(new MemoryStream(File.ReadAllBytes(filename))) as Bitmap; 

performs several transformations on them (rotation, scaling, alpha) and then saves the resulting PNG images back to disk with different file names based on the transformations applied

b.Save(outputName, ImageFormat.Png); 

I've successfully written thousands of PNGs using the utility. However, occasionally one of the PNGs fails to load in a separate program which uses libpng. In that program, libpng gives the error "Too many IDATs found"

Looking into the PNG file reveals a 'rogue' IDAT chunk at the end of the file just before the IEND chunk. One such IDAT chunk (and the following IEND chunk) looks like this in a hex editor. These are the final 24 bytes in the file.

IDAT: 0x00 0x00 0xFF 0xF4 0x49 0x44 0x41 0x54 0x35 0xAF 0x06 0x1E     IEND: 0x00 0x00 0x00 0x00 0x49 0x45 0x4e 0x44 0xAE 0x42 0x60 0x82 

The IDAT chunk length is shown as 0xFFF4. However, as is obvious, there aren't that many bytes in the IDAT chunk (or even the file for that matter.)

Has anyone else come across this problem? I can fix the problem in one of several ways. I can hand edit the PNG file to remove that last IDAT chunk (or set its size to 0.) I can run a secondary program which fixes broken PNGs. However, I'd like a C#/.NET solution which I can easily add to my original program. Ideally, I'd like a solution which doesn't require me to re-open the PNG as a binary file; check for the bad IDAT chunk; and re-write the PNG. However, I'm beginning to think that's what I'll need to do.

like image 875
David Welch Avatar asked Oct 10 '13 17:10

David Welch


People also ask

Why is my image's filename or encoder null?

filename or encoder is null. The image was saved with the wrong image format. The image was saved to the same file it was created from. The following example creates a Bitmap object from a BMP file. The code saves the bitmap to three JPEG files, each with a different quality level.

Can I save a JPG file as a PNG image?

You can also save it to your device. While any JPG can be saved as a PNG image, one main advantage of the PNG file format is that it supports an opacity channel, which will allow PNG images to be transparent while JPGs are not. Kapwing supports a background removal process that allows creators to create a transparent PNG from a JPG.

Why is my GDI+ file being saved as a PNG file?

When you use the Save method to save a graphic image as a Windows Metafile Format (WMF) or Enhanced Metafile Format (EMF) file, the resulting file is saved as a Portable Network Graphics (PNG) file. This behavior occurs because the GDI+ component of the .NET Framework does not have an encoder that you can use to save files as .wmf or .emf files.

What is a PNG file and how do I use it?

PNG files, however, can support transparent areas, so they can be shaped however you want. They're perfect for logos, signatures, overlays, watermarks, and emotes for Twitch, Discord, or Slack. Kapwing supports creating PNG files from a variety of image sources, and can also be used to make an image background completely transparent.


1 Answers

Old question.

.NET is notoriously poor at handling images. The codecs are old win32 ones with many bugs.

.NET does not always free up the OS resources used when reading/writing image files even if you follow the recommended dispose and/or using methods.

like image 155
JohnT Avatar answered Sep 21 '22 23:09

JohnT