背景:
我正在使用WPF编写一个条形码图像扫描仪桌面应用程序,它可以从文件位置(先前扫描的图像)或直接从扫描仪(使用NTWAIN)输入。在这两种情况下,我都创建或获取一个流。
现在,当我从流中创建一个新的位图并使用Encoder
将其保存为JPEG文件时 using (var bmp = Image.FromStream(rawStream))
{
EncoderParameter ratio = new EncoderParameter(Encoder.Quality, 100L);
EncoderParameter depth = new EncoderParameter(Encoder.ColorDepth, 8L);
EncoderParameters codecParams = new EncoderParameters(2);
codecParams.Param[0] = ratio;
codecParams.Param[1] = depth;
ImageCodecInfo jpegCodecInfo = ImageCodecInfo.GetImageEncoders().FirstOrDefault(x => x.FormatID == ImageFormat.Jpeg.Guid);
bmp.Save(file.FileFullPath, jpegCodecInfo, codecParams); // Save to JPG
}
或者内建的
bmp.Save(file.FileFullPath, ImageFormat.Jpeg);
我倾向于以更大的文件大小结束。当然,情况并非总是如此,但当我将一个小的黑白tiff文件加载到内存并编码为jpg时,绝对是正确的。
我对图像处理的知识是基本的,但我认为这是因为jpg文件以24位的颜色深度保存,而tiff图像最初存储为1位。(黑白)
无论我做什么,我都无法使jpg文件匹配原始文件的位深度。
我发现唯一的工作就是简单地将文件重命名为"filename.jpg"并保存为
using (Bitmap bmp = new Bitmap(rawStream))
{
Save(file.FileFullPath);
}
但这感觉就像一个解决方案,不会无限期地工作(作为一个附带的问题,可以简单地重命名任何*.bmp或*tiff文件到*.jpg,它仍然会工作吗?)
根据我的初步研究,似乎
bmp.Save()
不支持jpeg图像中位深度的编码参数。可以理解的是,我的客户对文件从16kb毫无理由地增长到200kb感到不高兴。
是否有一个已知的工作围绕这个问题,或者我错过了一些明显的东西,当它涉及到流和图像的工作?
JPEG最适合具有多种颜色、阴影和渐变的照片。典型位深:8(用于灰度)或24(用于全彩)。
如果您想要单色(1位),我建议不要使用JPEG,尤其是因为JPEG会引入编码伪影,这些伪影可能对照片无关紧要,但如果您的原始源是1位,则看起来就像"添加了胡椒和盐"。你越压缩它们,它们就会越多。
您应该尝试使用PNG代替,它没有这样的伪影,并且更适合具有锐利边缘的数字源。
您还可以尝试使用智能调整大小算法(例如使用8位输出)将TIFF缩小50%或75%,该算法将原始中的微点转换为输出中的小梯度。我很久以前用1位传真/扫描仪图像做过,实际上效果相当好。但时间太长了,无法保留这些资源