如何使用 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
。
要在 TIFF 文件中创建多个页面(目录),请使用 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 表示宽度和高度,并浮动 xre 和 yres。否则,va_args将无法为您的 tiff 文件获取正确的值。
我还发现了有用的字符串TIFFTAG_SOFTWARE和TIFFTAG_DATETIME,但不包括在下面的示例中。
我还将TIFFTAG_IMAGEWIDTH的原始版本从 image_width/spp 更改为仅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 writingn", 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;
}
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- C++:TypeDef使用元组
- 使用std::multimap迭代器创建std::list
- 从不同线程使用int64的不同字节安全吗
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么在全局范围内使用"extern int a"似乎不行?
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用Google Mock来模拟gettimeofday()
- 如何使用默认参数等选择模板专业化
- 为什么使用 "this" 指针调用派生成员函数?
- 如何使用 LibTIFF 在多页面上编写磁贴
- 使用 libtiff 在 C++ 中写入映像时出现问题,在 TIFFScanlineSize 中出现整数溢出
- 使用 libtiff 的 TIFFReadRawTile 无需解压缩/压缩即可获得 jpeg 磁贴
- 使用 LLVM 的 libc++ 时,__1 符号从何而来?
- 在std::cout之后使用std::cin时,换行符从何而来
- 为什么以及在何处在C++中使用引用和指针
- 使用LibTiff编译Ogre-未定义的引用
- 使用LibTiff逐像素写入tif
- 基例如何影响使用递归函数的哪些行