我正在尝试将 TIFF 图像存档在数据库中,并且我想尽可能地压缩图像,即使以更高的 CPU 使用率和高内存为代价。
为了测试 LibTiff.NET 中可用的压缩,我使用了以下代码(从这个示例修改):
//getImageRasterBytes and convertSamples are defined in the sample
void Main() {
foreach (Compression cmp in Enum.GetValues(typeof(Compression))) {
try {
using (Bitmap bmp = new Bitmap(@"D:\tifftest\200 COLOR.tif")) {
using (Tiff tif = Tiff.Open($@"D:\tifftest\output_{cmp}.tif", "w")) {
byte[] raster = utils.getImageRasterBytes(bmp, PixelFormat.Format24bppRgb);
tif.SetField(TiffTag.IMAGEWIDTH, bmp.Width);
tif.SetField(TiffTag.IMAGELENGTH, bmp.Height);
tif.SetField(TiffTag.COMPRESSION, cmp);
tif.SetField(TiffTag.PHOTOMETRIC, Photometric.RGB);
tif.SetField(TiffTag.ROWSPERSTRIP, bmp.Height);
tif.SetField(TiffTag.XRESOLUTION, bmp.HorizontalResolution);
tif.SetField(TiffTag.YRESOLUTION, bmp.VerticalResolution);
tif.SetField(TiffTag.BITSPERSAMPLE, 8);
tif.SetField(TiffTag.SAMPLESPERPIXEL, 3);
tif.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
int stride = raster.Length / bmp.Height;
utils.convertSamples(raster, bmp.Width, bmp.Height);
for (int i = 0, offset = 0; i < bmp.Height; i++) {
tif.WriteScanline(raster, offset, i, 0);
offset += stride;
}
}
}
} catch (Exception ex) {
//code was run in LINQPad
ex.Dump(cmp.ToString());
}
}
}
测试图像为200dpi 24bpp,1700宽2200高,使用LZW压缩;文件大小接近 7 MB。(该图像代表我要存储的图像。)
在确实有效的算法中(有些算法因各种错误而失败),最小的压缩文件是使用 创建的Compression.Deflate
,但它只压缩到 5MB,我希望它更小(小于 1MB)。
必须有一些更高压缩率的算法;包含此图像的 PDF 文件大约为 500Kb。
如果特定算法与其他 TIFF 查看器/库不兼容,这不是问题,只要我们可以从数据库中提取压缩的 TIFF 并将其转换为System.Drawing.Bitmap
使用 LibTiff.Net 或其他库。
如何通过无损压缩生成更小的文件?这甚至可能与这些类型的图像?
更新