views:

1300

answers:

1

I have function which takes a bitmap, copies part of it and saves it as 8bpp tiff. Filename of the result image is unique and file doesn't exist, program has permission to write 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();
    }

Weird thing is that this funcion works well on some computers (Win 7) and throws System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI exception on other computers (mostly Win XP).

All computers have the .NET 3.5 SP1 runtime installed.

If I use croped.Save(filename, ImageFormat.Tiff); instead 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 could be?

Thanks, Lukas

A: 

GDI is a windows operating system functionality. I encountered similar issues when dealing with 16-bit TIFF files, and resorted to a different library. See using LibTIFF from c#

The MSDN help suggest that the functionality is available, but at then Windows throws 'generic error' exceptions when you try 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 functioanity in Windows 7.

The other solution I have used is to make a unsafe copy in 8-bit. This way 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;

    }
Adriaan