问题描述
我有一个 c# 程序,它打开一个 .tif 图像,然后提供保存它的选项.但是,保存图像时质量总是会下降.
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.
(我在保存图像时传递了一些参数,以便质量为 100% 并且没有压缩,但实际唯一颜色的数量从 254 变为 16,即使图像属性显示 8bpp)
(有问题的图像是每像素 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;
}
这是我保存图像的方式:
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://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();
}
}
即使我不以任何方式调整图像大小或更改图像,我的质量也会有所下降.有什么建议吗?
Even if I don't resize or change the image in any ways, I experience a loss in quality. any advice?
推荐答案
System.Drawing 对 8 位图像的支持很差.从 24 位或 32 位图像转换为 8 位时;它将始终使用固定的默认调色板.该默认调色板仅包含 16 种灰色阴影,其他条目是各种颜色.
System.Drawing has poor support for 8-bit images. When converting from 24 or 32-bit images to 8-bit; it'll always use a fixed default color palette. That default color palette only contains 16 shades of grey, the other entries are various colors.
保存为.bmp"时是否遇到同样的问题?如果是,那么转换到 8 位格式之前已经发生了,您必须弄清楚您的程序在哪里执行此操作并在那里解决问题.如果只有 tiff 编码器转换为 8 位,则必须先在单独的步骤中进行 8 位转换.创建一个 8 位图像,用灰度调色板填充 Image.Palette
,然后将位图数据复制过来.
Do you have the same problem when saving as '.bmp'? If yes, then the conversion to the 8-bit format already happened earlier, you'll have to figure out where your program does that and fix the issue there.
If it's only the tiff encoder that converts to 8-bit, you'll have to do the 8-bit conversion in a separate step first. Create an 8-bit image, fill Image.Palette
with a gray-scale palette, and then copy the bitmap data over.
但是 System.Drawing 对 8 位图像的支持很差,并且有几种方法(例如 SetPixel
)在处理此类图像时只会抛出 InvalidOperationException
.您可能必须使用不安全的代码(使用 LockBits
等)来复制位图数据.如果我是你,我会看看你是否可以使用其他图形库.
But System.Drawing has poor support for 8-bit images, and several methods (e.g. SetPixel
) will just throw InvalidOperationException
when dealing with such images. You will probably have to use unsafe code (with LockBits
etc.) to copy the bitmap data. If I were you, I'd look if there are alternative graphics libraries you could use.
这篇关于使用 Image 类在 c# 中丢失图像质量(减少颜色数量)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!