我做的时候
b.Save(outputFilename, ImageFormat.Bmp);
其中b是16位位图,它使用位域压缩保存。如何在不使用任何压缩的情况下进行C#保存?
这就是我对@Ben Voigt发布的链接所做的:
ImageCodecInfo myImageCodecInfo;
Encoder myEncoder ;
EncoderParameter myEncoderParameter;
EncoderParameters myEncoderParameters;
myEncoder = Encoder.Compression;
myImageCodecInfo = GetEncoderInfo("image/bmp");
myEncoderParameters = new EncoderParameters(1);
myEncoderParameter = new EncoderParameter(myEncoder,
(long)EncoderValue.CompressionNone);
myEncoderParameters.Param[0] = myEncoderParameter;
b.Save(outputFilename, myImageCodecInfo, myEncoderParameters );
当我传递8位位图时,不使用压缩。但是当我传递一个16位RGB位图时,它仍然使用位域压缩。
答案 0 :(得分:6)
Save
函数的重载接受EncoderParameters
参数,通过该参数可以控制压缩。
请参阅http://msdn.microsoft.com/en-us/library/ytz20d80.aspx和http://msdn.microsoft.com/en-us/library/system.drawing.imaging.encoder.compression.aspx
答案 1 :(得分:5)
Windows中的位图意味着DIB。
“与设备无关的位图(DIB)是一种用于定义各种颜色分辨率的设备无关位图的格式.DIB的主要目的是允许位图从一个设备移动到另一个设备(因此,设备 - 与设备相关的位图相比,DIB是一种外部格式,它在系统中显示为位图对象(由应用程序创建...)。DIB通常在元文件中传输(通常使用StretchDIBits()函数),BMP文件和剪贴板(CF_DIB数据格式)。“
正如我们在评论中已经讨论的那样,BITFIELDS压缩仅用于16位和32位DIB,并简单描述了数据的打包方式。在16位DIB的情况下,它可以定义绿色通道的分辨率(即5:6:5或5:5:5),其中对于32位DIB,它定义数据是以RGB格式存储还是BGR顺序(以及使用BMIHv4 / 5标头时,是否使用了Alpha通道。)
只有一个原因。它是保持BMP与设备无关,这种格式与其可能使用的设备无关。因此,它意味着,它始终按照Windows的DIB格式保存!格式通过压缩保持不变。
EncoderParameters codecParams = new EncoderParameters(1);
codecParams.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
b.Save(outputFilename, myImageCodecInfo, codecparams );
这应该确保您的质量。
答案 2 :(得分:3)
看来你真正的需要不是“保存没有位域压缩的16位位图”,而是为了避免有损压缩。
问题在于16位位图格式本质上使用位域(红色为5位,绿色为6位,蓝色为5位),因此如果原始图像会丢失某些信息像素格式宽于16位。目前最常用的图像格式是RGB格式,每个像素使用8位,因此每像素需要3×8 = 24位。你根本无法将24位信息输入16位;有些位会掉下来,这是生活中的一个事实。
因此,只要需要16位位图,您的问题就无法解决。唯一的解决方法是避免使用16位位图。
注意:
即使您指定了“无压缩”,也使用位域压缩的原因是因为位域压缩不是真正的压缩;它只是一种像素格式,因此应称为“位域格式”而不是“位域压缩”。 RLE是一种真正的(尽管非常简单)压缩方法。
RLE代表“运行长度编码”并且其工作如下:长度为N的一系列相同像素值被数字N代替,随后是像素值的单个出现。所以,RLE绝对是无损的。