使C#保存16位位图而不压缩位字段

使C#保存16位位图而不压缩位字段,c#,bitmap,C#,Bitmap,当我做一个 b.Save(outputFilename, ImageFormat.Bmp); 其中b是一个16位位图,它与位域压缩一起保存。如何在不使用任何压缩的情况下进行C#save 这就是我对@Ben Voigt发布的链接所做的: ImageCodecInfo myImageCodecInfo; Encoder myEncoder ; EncoderParameter myEncoderParameter; EncoderParameters myEncoderParameters; m

当我做一个

b.Save(outputFilename, ImageFormat.Bmp);
其中b是一个16位位图,它与位域压缩一起保存。如何在不使用任何压缩的情况下进行C#save

这就是我对@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位图时,它仍然使用位域压缩。

有一个超负荷的
Save
函数,该函数接受一个
EncoderParameters
参数,通过该参数可以控制压缩


请参阅和

windows中的位图表示DIB

“设备独立位图(DIB)是一种用于以各种颜色分辨率定义设备独立位图的格式。DIB的主要目的是允许位图从一个设备移动到另一个设备(因此,名称的设备独立部分).DIB是一种外部格式,与设备相关位图不同,它在系统中显示为位图对象(由应用程序创建…)。DIB通常以元文件(通常使用StretchDIBits()函数)、BMP文件和剪贴板(CF_DIB数据格式)的形式传输。”


正如我们在评论中已经讨论过的,位域压缩只在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 ); 

这应该可以确保您的质量。

看来您真正需要的不是“保存16位位图而不进行位域压缩”,而是避免有损压缩

问题是16位位图格式本质上使用位域(例如5位表示红色,6位表示绿色,另外5位表示蓝色),因此如果原始图像的像素格式大于16位,则会丢失一些信息。现在最常用的图像格式是RGB格式,它每像素使用8位,因此它需要每像素3×8=24位。你根本无法将24位信息放入16位;有些碎片会脱落,这是生活的事实

因此,只要需要16位位图,您的问题就无法解决。唯一的解决办法是避免使用16位位图

注:

尽管指定了“无压缩”,但仍使用位字段压缩的原因是位字段压缩不是真正的压缩;它只是一种像素格式,所以应该称为“位域格式”,而不是“位域压缩”。RLE是一种真正的(尽管非常简单)压缩方法


RLE代表“运行长度编码”,其工作原理如下:长度为N的一系列相同像素值被替换为数字N,后跟像素值的一次出现。因此,RLE是绝对无损的。

位字段压缩仅用于16位和32位DIB,并简单描述了数据的压缩方式。对于16位DIB,它可以定义绿色通道的分辨率(即5:6:5或5:5:5),其中对于32位DIB,它定义数据是否以RGB或BGR顺序存储(以及在使用BMIHv4/5报头时,是否使用alpha通道)您能告诉我们为什么要避免位域压缩?为什么不压缩就无法保存?为什么不喜欢PNG文件格式?对于bmp,我们已经讨论得够多了。好吧,我必须考虑它。@MikeNakis当然,它们只是定义。说到这里,我已经告诉他,它的面具是用来包装的。我已经尽可能多地讨论了。你们所说的那个些抄袭的段落并不是真的,只是从书中摘录的。我也给了他这些链接的引用。我给出了那个代码,只是为了以防万一,他从某处获取图像并再次编码。我看到他并没有试图把32个基点减到16个基点。但他从未回答自己的图像是来自服务器还是来自何处。所以我的回答和你一样笼统。那么你是说没有压缩我无法保存它?到目前为止,MS不喜欢这样。DIB就是它给我们的!这是一本很好的书,虽然不是完全回答你的问题,但是很好-找到一本有趣的书-享受!!讲述了多年来格式的演变!EncoderParameters codeparams=新的EncoderParameters(1);codeparams.Param[0]=新的编码器参数(Encoder.Quality,100L);b、 保存(outputFilename、MyImageCodeInfo、CodeParams);你能试试这个告诉我吗。这应该能解决你的问题。为什么您不喜欢无损可证明的PNG格式呢。对于你的上述问题,它们是不同的。RLE不适用于16位或更多深度的图像。所以我希望,.Net framework也不会有它。试试上面的代码,据说可以进行无损转换。最重要的是,你从哪里获得这些图像?你所说的“因此,RLE绝对肯定是绝对无损的,但如果基础像素格式是有损的,这并没有帮助。”?如果你使用有损像素格式,如16位,然后用RLE压缩,会有信息丢失,但这不是由于RLE,这将是由于使用了有损像素格式。像素深度与有损像素没有这种联系。有损或无损取决于压缩算法。我不明白为什么不能进行16位无损压缩。RLE不能应用于16 bpp或32 bpp。只能对此类位图应用位字段压缩。RLE使用8 bpp位图。我加入了代码以保持质量不变,即使在