Libtiff
lastmod 2026-11-10created 2018-11-227 edits
libtiff is the standard C library for reading and writing TIFF (Tagged Image File Format) image files. It supports scanline-, strip-, and tile-based I/O, multiple compression schemes such as LZW, Deflate, and JPEG, multi-page files, and a range of bit depths and sample formats, and it handles tags and pixel data through functions such as TIFFOpen, TIFFSetField, and TIFFWriteScanline. Most image processing software, including OpenCV, GDAL, and ImageMagick, uses this library for TIFF support.
Save 1-bit TIFF File example
void SaveTiff(std::vector<cv::Mat> image_stack, std::string file)
{
const char* filec = file.c_str();
TIFF* tif = TIFFOpen(filec, "w");
if (tif) {
for (unsigned int i = 0; i < image_stack.size(); ++i) {
int imagewidth = image_stack[i].cols;
int imageheight = image_stack[i].rows;
int nr_channels = image_stack[i].channels();
bool fp32 = (image_stack[i].type() == CV_32FC1);
std::vector<unsigned char> buf(imagewidth
* (nr_channels == 3 ?
sizeof(uchar) * nr_channels : (fp32 ? sizeof(float) : sizeof(uchar))), 255);
//unsigned char buf[] ;
void* raster = nullptr;
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, imagewidth);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, imageheight);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
//TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, nr_channels == 3 ? PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
TIFFSetField(tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
TIFFSetField(tif, TIFFTAG_PAGENUMBER, i, image_stack.size());
//TIFFSetField(tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
TIFFSetField(tif, TIFFTAG_PREDICTOR, 1);
cv::Mat image = image_stack[i];
assert(nr_channels == 3);
for (int y = 0; y < imageheight; ++y) {
int index = -1;
for (int x = 0; x < imagewidth; x++) {
buf[++index] = image.at<cv::Vec3b>(y, x)[0];
}
TIFFWriteScanline(tif, buf.data(), y, 0);
}
}
TIFFWriteDirectory(tif);
}
}
TIFFClose(tif);
}
See also
Favorite site
References
-
PluginTIFF.cpp.zip ↩