System.Drawing.Image.Save throws ExternalException: General error in GDI

I have a function that takes a bitmap, copies part of it, and saves it as an 8bpp tiff. The name of the result image file is unique and the file does not exist, the program has write permission to the target folder.

void CropImage(Bitmap map) { Bitmap croped = new Bitmap(200, 50); using (Graphics g = Graphics.FromImage(croped)) { g.DrawImage(map, new Rectangle(0, 0, 200, 50), ...); } var encoderParams = new EncoderParameters(2); encoderParams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 8L); encoderParams.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionNone); croped.Save(filename, tiffEncoder, encoderParams); croped.Dispose(); } 

It is strange that this function works well on some computers (Win 7) and generates a System.Runtime.InteropServices.ExternalException: A general error occurred in the GDI exception on other computers (mainly Win XP).

All computers have the .NET 3.5 SP1 runtime installed.

If I use croped.Save(filename, ImageFormat.Tiff); instead of croped.Save(filename, tiffEncoder, encoderParams); than it works on all computers, but I need to save Tiff in 8bpp format.

Do you have any ideas where the problem might be?

Thanks Lucas

+4
source share
1 answer

GDI is the functionality of the Windows operating system. I encountered similar problems when working with 16-bit TIFF files and turned to another library. See using LibTIFF from C #

MSDN Help indicates that the functionality is available, but with exceptions, Windows generates a โ€œgeneral errorโ€ when trying to copy a bitmap into a new bitmap or save it to a file or stream. Indeed, the same functionality works well on Windows7 (which seems to have good TIFF support). See New WIC Functionality in Windows 7 .

Another solution I used is to create an unsafe copy in the 8-bit version. Thus, I was able to save PNG files (with palette). I have not tried this for TIFF.

  // part of a function taking a proprietary TIFF tile structure as input and saving it into the desired bitmap format // tile.buf is a byterarray, containing 16-bit samples from TIFF. bmp = new Bitmap(_tile_width, _tile_height, PixelFormat.Format8bppIndexed); System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height); BitmapData bmpData =bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,bmp.PixelFormat); int bytes = bmpData.Stride * bmp.Height; dstBitsPalette = (byte *)bmpData.Scan0; offset=0; for (offset = 0; offset < _tile_size; offset += 2) { dstBitsPalette[offset >> 1] = tile.buf[offset + 1]; } // setup grayscale palette ColorPalette palette = bmp.Palette; for (int i = 0; i < 256; i++) { Color c = Color.FromArgb(i, i, i); palette.Entries[i] = c; } bmp.Palette = palette; bmp.UnlockBits(bmpData); return bmp; } 
+1
source

All Articles