【发布时间】:2013-01-26 12:23:57
【问题描述】:
我正在尝试使用 FreeImage.Net 和 C# 将 JPEG 转换为带有 JPEG 压缩的 TIFF。这很好用,但是,对于低质量的 JPGES,TIFF 文件比原始文件大很多。我假设 TIFF 大小不依赖于原始 JPEG 质量,因为输出图像的大小始终大致相同。
例如(转换截图):
2065kb JPEG (quality: 100%) --> 1282kb TIFF
379kb JPEG (quality: 50%) --> 1200kb TIFF
我们公司不能接受这种规模的增加,因为我们的客户和我们正在处理大量的文件。
有趣的是,当我使用 GIMP 转换图像时,我得到了大致相同的结果。现在我想知道:这是根据 TIFF 标准还是 FreeImage/GIMP 特有的?(我认为两者都使用 libtiff.dll)。
我想还有另一种方法,因为我们公司有一台扫描仪,它可以生成尺寸更小的 JPEG 压缩 TIFF 图像。 有谁知道另一个库(无论是否免费)可以更有效地处理这种转换,或者在 FreeImage 中实现这一点?
更新:
我查看了TIFF 6.0 specification,分析了我们的扫描仪生成的文件,并能够编写一个将 JPEG 包装到一个非常简单的 TIFF 容器中的函数(也适用于合并到多页的多个 JPEG TIFF)。
对于那些对 TIFF 有一点了解的人:我制作了一个新的 TIFF 文件(根据图像/页的数量,包含一个或多个 IFD)并将现有 JPEG 图像的原始数据写入单个条带(每IFD),使用以下字段/条目:
NewSubfileType = 0
ImageWidth = //(width of the original JPEG)
ImageLength = //(height of the original JPEG)
BitsPerSample = {8, 8, 8} //(count: 3)
Compression = 7 //(JPEG)
PhotometricInterpretation = 6 //(YCbCr)
StripOffsets = //(offset of raw JPEG data, count: 1)
SamplesPerPixel = 3
RowsPerStrip = //(height of the original JPEG)
StripByteCounts = //(length of raw JPEG data, count: 1)
XResolution = //(horizontal resolution of original JPEG data)
YResolution = //(vertical resolution of original JPEG data)
PlanarConfiguration = 1 (chunky)
ResolutionUnit = 2 //(Inch)
(为了获取原图的信息,我使用了FreeImage,其他的图片库应该也可以。)
我知道可能存在一些我还不知道的陷阱。它可能不适用于任何 JPEG 文件。另外,我不确定为什么必须使用PhotometricInterpretation = 6 和PlanarConfiguration = 1 或其他一些字段的值。但是,它有效。
我想我对其他库的问题是,他们生成了一个始终具有相同质量的全新 JPEG(因为您只能将 TIFF 压缩设置为 JPEG,但不能指定任何其他选项)并将其包装到 TIFF 容器中.
我现在也知道,TIFF 中的 JPEG 压缩并不是最好的选择(它有损、不常见且很少支持,除了 JPEG 压缩的 TIFF 并不比普通的 JPEG 文件好)。但是,我们的客户要求这样做。让我们看看上面是否会是一个合适的解决方案,或者我是否设法找到其他东西。
【问题讨论】:
-
这就是图像处理的“天下没有免费的午餐”原则。您必须关闭试图挽救低质量 jpeg 图像的插值器。等效的 .NET 属性是 Graphics.InterpolationMode
-
@HansPassant 这听起来很有希望。如果在转换过程中确实进行了插值,这将解释生成的 tiff 的大小大致相等。但是,到目前为止,我还没有找到关闭它的方法。我想问题是,FreeImage(或其他库)将图像加载为像素矩阵,并在将其保存为 tiff 时再次使用 jpeg-compression 压缩它,而不是直接将原始文件嵌入到 tiff-container 中。后者是我想做的。
标签: c# image-processing jpeg tiff freeimage