Frage In einem TIFF erstellen Sie ein Sub IFD mit Thumbnail (libtiff)


Ich weiß, dass thumbnail.c etwas Code enthält, der ein Thumbnail erstellt und es in eine Sub-IDF legt, aber in diesem Code ist viel los (das Thumbnail erzeugen, eine Kontrastkurve anwenden usw.) und ich habe Schwierigkeiten, gerade zu reproduzieren ein Thumbnail schreiben. Google war auch keine Hilfe.

Meine Frage ist, nachdem ich eine Ausgabedatei geöffnet habe und ein TIFF * habe, habe ich meine Miniaturbilddaten bereit (ebenso wie meine Hauptbilddaten), wie füge ich sie so hinzu, dass das Miniaturbild darin ist eine Sub-IFD des Hauptbildes IFD?


7
2017-08-14 19:41


Ursprung


Antworten:


Nachdem ich eine Weile über den libtiff-Quellcode geforscht habe, bin ich in tif_dirwrite.c auf dieses Thema gestoßen:

 /*
 * Copyright (c) 1988-1997 Sam Leffler
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and
 * its documentation for any purpose is hereby granted without fee, provided
 * that (i) the above copyright notices and this permission notice appear in
 * all copies of the software and related documentation, and (ii) the names of
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
 * publicity relating to the software without the specific, prior written
 * permission of Sam Leffler and Silicon Graphics.
 */

...
if (!n)
    return(0);
/*
 * Total hack: if this directory includes a SubIFD
 * tag then force the next <n> directories to be
 * written as ``sub directories'' of this one.  This
 * is used to write things like thumbnails and
 * image masks that one wants to keep out of the
 * normal directory linkage access mechanism.
 */
tif->tif_flags|=TIFF_INSUBIFD;
tif->tif_nsubifd=tif->tif_dir.td_nsubifd;
if (tif->tif_dir.td_nsubifd==1)
    tif->tif_subifdoff=0;
else
    tif->tif_subifdoff=m;
return(1);
...

(Ich habe die Copyrightinformationen hinzugefügt, weil ich nicht sicher war, ob ich es tun musste, wenn ich hier einen Code aus der Bibliothek postete)

Also, um meine eigene Frage zu beantworten (wie man ein Thumbnail in eine Sub-IFD des Hauptbild-IFD schreibt):

//...
//For the sake of this demo we will assume that I have opened a 
//TIFF (TIFF* created_TIFF) in write mode and have included the correct header
//files

//set all of your TIFF fields for the main image
//...

//Define the number of sub-IFDs you are going to write
//(assuming here that we are only writing one thumbnail for the image):
int number_of_sub_IFDs = 1;
toff_t sub_IFDs_offsets[1] = { 0UL };

//set the TIFFTAG_SUBIFD field:
if(!TIFFSetField(created_TIFF, TIFFTAG_SUBIFD, number_of_sub_IFDs, 
    sub_IFDs_offsets))
{
    //there was an error setting the field
}

//Write your main image raster data to the TIFF (using whatever means you need,
//such as TIFFWriteRawStrip, TIFFWriteEncodedStrip, TIFFWriteEncodedTile, etc.)
//...

//Write your main IFD like so:
TIFFWriteDirectory(created_TIFF);

//Now here is the trick: like the comment in the libtiff source states, the 
//next n directories written will be sub-IFDs of the main IFD (where n is 
//number_of_sub_IFDs specified when you set the TIFFTAG_SUBIFD field)

//Set up your sub-IFD
if(!TIFFSetField(created_TIFF, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE))
{
    //there was an error setting the field
}

//set the rest of the required tags here, as well as any extras you would like
//(remember, these refer to the thumbnail, not the main image)
//...

//Write this sub-IFD:
TIFFWriteDirectory(created_TIFF);

//Assuming you are only writing one sub-IFD and are done with the file, you 
//can close it now. If you specified more than one sub-IFD, you need repeat 
//the above code (starting where we set TIFFTAG_SUBFILETYPE) for each of your
//sub-IFDs
TIFFClose(created_TIFF);

Ich hoffe, dass dies jemandem hilft und dass sie nicht so viel Kraft aufbringen müssen, um herauszufinden, wie das geht. Es ist wirklich eine Schande, dass libtiff so schlecht dokumentiert ist, besonders wenn man bedenkt, wie weit es benutzt wird.


5
2017-08-17 00:44