Как писать плитки на нескольких страницах, используя LibTIFF - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь написать плитки на многостраничном TIFF (пирамидальном TIFF), используя LibTIFF:

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);   
}

Когда я пытался написать только одну страницу, я работал нормально. Но при попытке сделать с несколькими страницами, результат показывает перекрывающиеся изображения. Казалось, что все страницы показаны на первой странице.

Я проверил полученный файл TIFF с помощью команды tiffinfo. Он показывает, что номер страницы является номером последней страницы, но он показывает только информацию о первой странице (т.е. показывает только одну страницу).

Существуют ли другие настройки для написания плиток на многостраничном пирамидальном TIFF?

(я также пытался установить FILETYPE_PAGE как TIFFTAG_SUBFILETYPE.)

Ответы [ 2 ]

0 голосов
/ 15 апреля 2019

Я нашел эту версию https://www.asmail.be/msg0055065771.html самый полезный. Одно предупреждение , обязательно используйте заявленное uint16 для spp, bpp, photo и res_unit, uint32 для ширины и высоты, и float для xres и 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 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;
}
0 голосов
/ 07 января 2019

Чтобы создать несколько страниц (каталогов) в файле 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);
...