如何使用 LibTIFF 在多页上写入图块
How to write tiles on multi pages using LibTIFF
我正在尝试使用 LibTIFF 在多页 tiff(金字塔形 tiff)上编写图块:
for(int pageNum=0; pageNum<pageCount; pageNum++)
{
// processing for getting tiles (decode and resize for each page)
////
TIFFSetField(tiff_out, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE);
TIFFSetField(tiff_out, TIFFTAG_PAGENUMBER, pageNum);
//TIFFSetField(tiff_out, TIFFTAG_IMAGEWIDTH, imageWidth); // <- cannot be done with en error message(cannot change the value while processing)
//TIFFSetField(tiff_out, TIFFTAG_IMAGELENGTH, imageHeight); // <- cannot be done with en error message(cannot change the value while processing)
TIFFWriteEncodedTile(tiff_out, tileNumberOnPage, buff, -1);
}
当我尝试只写单页时,我工作得很好。
但是当尝试处理多页时,结果会显示重叠的图像。
似乎所有页面都显示在第一页。
我用 tiffinfo
命令检查了生成的 TIFF 文件。
显示页码是最后一页,但只显示第一页的信息(即只显示一页)
在多页、金字塔形 TIFF 上是否有其他设置来写入图块?
(我也尝试将 FILETYPE_PAGE
设置为 TIFFTAG_SUBFILETYPE
。)
要创建 mutliple pages (directories) in the TIFF file,请使用 TIFFWriteDirectory
函数。它将指定的标签和数据写入当前目录,并开始一个新目录。 TIFFClose
将标签和数据写入当前目录并关闭文件。
因此,要创建一个包含两个目录的文件,您首先要创建一个新文件,设置标签并写入磁贴,调用TIFFWriteDirectory
,设置标签并写入磁贴,然后调用TIFFClose
。
例如,您可以将代码修改为:
for(int pageNum=0; pageNum<pageCount; pageNum++)
{
// processing for getting tiles (decode and resize for each page)
if(pageNum>0) {
TIFFWriteDirectory(tiff_out);
}
TIFFSetField(tiff_out, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE);
TIFFSetField(tiff_out, TIFFTAG_IMAGEWIDTH, imageWidth);
TIFFSetField(tiff_out, TIFFTAG_IMAGELENGTH, imageHeight);
TIFFWriteEncodedTile(tiff_out, tileNumberOnPage, buff, -1);
}
TIFFClose(tiff_out);
我找到了这个版本 https://www.asmail.be/msg0055065771.html
最有帮助的。一个警告,确保使用已声明的
uint16 用于 spp、bpp、照片,以及 res_unit、uint32 用于宽度和高度,
xres 和 yres 的 float。
否则 va_args 将无法为您的 tiff 文件获取正确的值。
我还发现有用的 TIFFTAG_SOFTWARE 和 TIFFTAG_DATETIME 是字符串,但不包括在下面的示例中。
我还把 TIFFTAG_IMAGEWIDTH 的原件从 image_width / spp 改成了 just
image_width,这对我的彩色图像 (3) 不正确。
#include <stdio.h>
#include "tiffio.h"
#define XSIZE 256
#define YSIZE 256
#define NPAGES 10
int main (int argc, char **argv)
{
uint32 image_width, image_height;
float xres, yres;
uint16 spp, bpp, photo, res_unit;
TIFF *out;
int i, j;
uint16 page;
unsigned char array[XSIZE * YSIZE];
for (j = 0; j < YSIZE; j++)
for(i = 0; i < XSIZE; i++)
array[j * XSIZE + i] = (unsigned char)(i * j);
out = TIFFOpen("out.tif", "w");
if (!out)
{
fprintf (stderr, "Can't open %s for writing\n", argv[1]);
return 1;
}
image_width = XSIZE;
image_height = YSIZE;
spp = 1; /* Samples per pixel */
bpp = 8; /* Bits per sample */
photo = PHOTOMETRIC_MINISBLACK;
for (page = 0; page < NPAGES; page++)
{
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, image_width);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, image_height);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bpp);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photo);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
/* It is good to set resolutions too (but it is not nesessary) */
xres = yres = 100;
res_unit = RESUNIT_INCH;
TIFFSetField(out, TIFFTAG_XRESOLUTION, xres);
TIFFSetField(out, TIFFTAG_YRESOLUTION, yres);
TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, res_unit);
/* We are writing single page of the multipage file */
TIFFSetField(out, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
/* Set the page number */
TIFFSetField(out, TIFFTAG_PAGENUMBER, page, NPAGES);
for (j = 0; j < image_height; j++)
TIFFWriteScanline(out, &array[j * image_width], j, 0);
TIFFWriteDirectory(out);
}
TIFFClose(out);
return 0;
}
我正在尝试使用 LibTIFF 在多页 tiff(金字塔形 tiff)上编写图块:
for(int pageNum=0; pageNum<pageCount; pageNum++)
{
// processing for getting tiles (decode and resize for each page)
////
TIFFSetField(tiff_out, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE);
TIFFSetField(tiff_out, TIFFTAG_PAGENUMBER, pageNum);
//TIFFSetField(tiff_out, TIFFTAG_IMAGEWIDTH, imageWidth); // <- cannot be done with en error message(cannot change the value while processing)
//TIFFSetField(tiff_out, TIFFTAG_IMAGELENGTH, imageHeight); // <- cannot be done with en error message(cannot change the value while processing)
TIFFWriteEncodedTile(tiff_out, tileNumberOnPage, buff, -1);
}
当我尝试只写单页时,我工作得很好。 但是当尝试处理多页时,结果会显示重叠的图像。 似乎所有页面都显示在第一页。
我用 tiffinfo
命令检查了生成的 TIFF 文件。
显示页码是最后一页,但只显示第一页的信息(即只显示一页)
在多页、金字塔形 TIFF 上是否有其他设置来写入图块?
(我也尝试将 FILETYPE_PAGE
设置为 TIFFTAG_SUBFILETYPE
。)
要创建 mutliple pages (directories) in the TIFF file,请使用 TIFFWriteDirectory
函数。它将指定的标签和数据写入当前目录,并开始一个新目录。 TIFFClose
将标签和数据写入当前目录并关闭文件。
因此,要创建一个包含两个目录的文件,您首先要创建一个新文件,设置标签并写入磁贴,调用TIFFWriteDirectory
,设置标签并写入磁贴,然后调用TIFFClose
。
例如,您可以将代码修改为:
for(int pageNum=0; pageNum<pageCount; pageNum++)
{
// processing for getting tiles (decode and resize for each page)
if(pageNum>0) {
TIFFWriteDirectory(tiff_out);
}
TIFFSetField(tiff_out, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE);
TIFFSetField(tiff_out, TIFFTAG_IMAGEWIDTH, imageWidth);
TIFFSetField(tiff_out, TIFFTAG_IMAGELENGTH, imageHeight);
TIFFWriteEncodedTile(tiff_out, tileNumberOnPage, buff, -1);
}
TIFFClose(tiff_out);
我找到了这个版本 https://www.asmail.be/msg0055065771.html 最有帮助的。一个警告,确保使用已声明的 uint16 用于 spp、bpp、照片,以及 res_unit、uint32 用于宽度和高度, xres 和 yres 的 float。 否则 va_args 将无法为您的 tiff 文件获取正确的值。
我还发现有用的 TIFFTAG_SOFTWARE 和 TIFFTAG_DATETIME 是字符串,但不包括在下面的示例中。
我还把 TIFFTAG_IMAGEWIDTH 的原件从 image_width / spp 改成了 just image_width,这对我的彩色图像 (3) 不正确。
#include <stdio.h>
#include "tiffio.h"
#define XSIZE 256
#define YSIZE 256
#define NPAGES 10
int main (int argc, char **argv)
{
uint32 image_width, image_height;
float xres, yres;
uint16 spp, bpp, photo, res_unit;
TIFF *out;
int i, j;
uint16 page;
unsigned char array[XSIZE * YSIZE];
for (j = 0; j < YSIZE; j++)
for(i = 0; i < XSIZE; i++)
array[j * XSIZE + i] = (unsigned char)(i * j);
out = TIFFOpen("out.tif", "w");
if (!out)
{
fprintf (stderr, "Can't open %s for writing\n", argv[1]);
return 1;
}
image_width = XSIZE;
image_height = YSIZE;
spp = 1; /* Samples per pixel */
bpp = 8; /* Bits per sample */
photo = PHOTOMETRIC_MINISBLACK;
for (page = 0; page < NPAGES; page++)
{
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, image_width);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, image_height);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bpp);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photo);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
/* It is good to set resolutions too (but it is not nesessary) */
xres = yres = 100;
res_unit = RESUNIT_INCH;
TIFFSetField(out, TIFFTAG_XRESOLUTION, xres);
TIFFSetField(out, TIFFTAG_YRESOLUTION, yres);
TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, res_unit);
/* We are writing single page of the multipage file */
TIFFSetField(out, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
/* Set the page number */
TIFFSetField(out, TIFFTAG_PAGENUMBER, page, NPAGES);
for (j = 0; j < image_height; j++)
TIFFWriteScanline(out, &array[j * image_width], j, 0);
TIFFWriteDirectory(out);
}
TIFFClose(out);
return 0;
}