I am trying to archive TIFF images in a database, and I would like to compress the images as much as possible, even at the cost of higher CPU usage and high memory.
In order to test the compressions available in LibTiff.NET, I used the following code (modified from this sample):
//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());
}
}
}
The test image is 200dpi 24bpp, 1700 width by 2200 height, and using LZW compression; the file size is nearly 7 MB. (The image is representative of the images I want to store.)
Of the algorithms that did work (some failed with various errors), the smallest compressed file was created using Compression.Deflate
, but that only compressed to 5MB, and I would like it significantly smaller (under 1 MB).
There must be some algorithm for higher compression; a PDF file containing this image is something like 500Kb.
If a specific algorithm is incompatible with other TIFF viewers/libraries, this is not an issue, as long as we can extract the compressed TIFF from the database and convert it to a System.Drawing.Bitmap
using LibTiff.Net or some other library.
How can I generate even smaller files with lossless compression? Is this even possible with these kinds of images?
Update