加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

使用Image类在c#中丢失图像质量(减少颜色数量)

发布时间:2020-12-15 21:42:07 所属栏目:百科 来源:网络整理
导读:我有一个c#程序打开.tif图像,后来提供了保存它的选项.但是,保存图像时质量始终会下降. (编辑:我保存图像时传递了一些参数,使质量达到100%并且没有压缩,但实际独特颜色的数量从254到16,即使图像属性显示为8bpp) (EDIT2:有问题的图像是每像素8位的灰度图像
我有一个c#程序打开.tif图像,后来提供了保存它的选项.但是,保存图像时质量始终会下降.

(编辑:我保存图像时传递了一些参数,使质量达到100%并且没有压缩,但实际独特颜色的数量从254到16,即使图像属性显示为8bpp)

(EDIT2:有问题的图像是每像素8位的灰度图像 – 256种颜色/灰度阴影 – 我测试的每像素24位彩色图像不会发生这种情况,所有颜色都保留在这里.我开始了认为图像类可能只支持16种灰度

我该如何避免这种情况?

这是打开图像的代码:

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;
}

这是我保存图像的方式:

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://EDITED -STILL DOES NOT RESOLVE THE ISSUE
               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();
    }
}

即使我没有以任何方式调整图像大小或改变图像,我也会遇到质量损失.任何建议?

解决方法

System.Drawing对8位图像的支持很差.从24位或32位图像转换为8位图像时;它总是使用固定的默认调色板.该默认调色板仅包含16种灰度,其他条目为各种颜色.

保存为“.bmp”时,您是否遇到同样的问题?如果是,那么转换为8位格式已经发生在早期,你必须弄清楚你的程序在哪里做并解决问题.
如果只有tiff编码器转换为8位,则必须先在单独的步骤中进行8位转换.创建一个8位图像,用灰度调色板填充Image.Palette,然后复制位图数据.

但是System.Drawing对8位图像的支持很差,并且在处理这些图像时,几种方法(例如SetPixel)只会抛出InvalidOperationException.您可能必须使用不安全的代码(使用LockBits等)来复制位图数据.如果我是你,我会看看是否有你可以使用的替代图形库.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读