I have a c# program that opens a .tif image and later offers the option to save it. However, there is always a drop in quality when saving the image.

I passed some parameters while saving the image so that the quality is at 100 % and there is no compression, but the number of actual unique colors go from 254 (in the original image) to 16(in the saved image) with a clear loss in quality/information, even though the image properties show 8bpp. Displaying the image in a picturebox also shows reduced quality, so I am thinking that the problem is opening the image but so far, I haven't been able to resolve the issue

How do I avoid this?

Here's the code for opening the image:

public Image imageImport(){
            Stream myStream = null;
            OpenFileDialog openTifDialog = new OpenFileDialog();
            openTifDialog.Title = "Open Desired Image";
            openTifDialog.InitialDirectory = @"c:\";
            openTifDialog.Filter = "Tiff only (*.tif)|*.tif";
            openTifDialog.FilterIndex = 1;
            openTifDialog.RestoreDirectory = true;
            if (openTifDialog.ShowDialog() == DialogResult.OK)
            {   try
                {
                    if ((myStream = openTifDialog.OpenFile()) != null)
                    {
                        using (myStream)
                        {
                            String tifFileName= openTifDialog.FileName;
                            imgLocation = tifFileName;
                            Bitmap tifFile = new Bitmap(tifFileName);
                            return tifFile;

                        }
                    }
                }
                catch (Exception ex)
                {
    MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
                }

            }
            return null;

        }

This is the way I save the image:

private void saveImage(Image img){
        SaveFileDialog sf = new SaveFileDialog();
        sf.Title = "Select File Location";
        sf.Filter = " bmp (*.bmp)|*.bmp|jpeg (*.jpg)|*.jpg|tiff (*.tif)|*.tif";
        sf.FilterIndex = 4;
        sf.RestoreDirectory = true;
        sf.ShowDialog();

        // If the file name is not an empty string open it for saving.
        if (sf.FileName != "")
        {
            // Saves the Image via a FileStream created by the OpenFile method.
            System.IO.FileStream fs =
               (System.IO.FileStream)sf.OpenFile();
            // Saves the Image in the appropriate ImageFormat based upon the
            // File type selected in the dialog box.
            // NOTE that the FilterIndex property is one-based.
            switch (sf.FilterIndex)
            {
                case 1:
                    img.Save(fs,
                       System.Drawing.Imaging.ImageFormat.Bmp);
                    break;

                case 2:
                    img.Save(fs,
                       System.Drawing.Imaging.ImageFormat.Jpeg);
                    break;

                case 3://only one i am currently using
                    ImageCodecInfo codecInfo = ImageClass.GetEncoderInfo(ImageFormat.Tiff);
                     EncoderParameters parameters = new EncoderParameters(2);
                     parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality,100L);
                     parameters.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionNone);
                    img.Save(fs,codecInfo, parameters);
                    break;
            }

            fs.Close();



        }
    }

Even if I don't resize or change the image in any ways, I experience a loss in quality. any advice?

Also tried opening the file with:Image tiffImage = Image.FromFile(tiffFileName, true); no improvement

Also, the image in question is a grayscale image at 8 bits per pixel - 256 colors/shades of gray - This doesn't happen with a 24 bits per pixel color image that I tested where all the colors are retained. I am starting to think that the image class may only support 16 shades of gray

Hi edwingk, or anyone else who stumbles across this!

What you've encountered is probably the same bug in the .NET tiff loading routine that I've come across several times. A coworker complained to MS about it; they essentially shrugged and told him to live with it. However, there are workarounds. Try this:

Stream imageStreamSource = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
TiffBitmapDecoder decoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
int frame =0; // adjust/ loop for multiframe tiffs
BitmapSource bitmapSource = decoder.Frames[0];

// this piece works for 8-bit grayscale. Adjust for other formats.
Bitmap bmp = new Bitmap(bitmapSource.PixelWidth, bitmapSource.PixelHeight, PixelFormat.Format8bppIndexed);
BitmapData data = bmp.LockBits(new Rectangle(System.Drawing.Point.Empty, bmp.Size), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
bitmapSource.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
bmp.UnlockBits(data);

Well for saving, you could always just write the image to a file with a byte array. Of course this involves creating the header for the file. (however if you read it in as a Byte array that could get around it).

I know that's how I got around an issue of mine, where I altered the header of a Bitmap image to be larger then they usually are. The only way to preserve it was to save the byte array as a byte stream (and let the PC do what it does best and read the header and see it was a bitmap).

Pretty much when it doubt, look at the bytes, see if you can work with them instead of the Image related libraries (once had to resize an image, wanted to keep it as 8 bit look ... only way was to manually create each pixel)

This article has been dead for over six months. Start a new discussion instead.