2012-08-14 8 views
7

So che thumbnail.c include un codice che crea una miniatura e la colloca in un sub IDF, ma c'è molto da fare in quel codice (generando la miniatura, applicando una curva di contrasto, ecc.) e ho difficoltà a riprodurre semplicemente una miniatura. Anche Google non ha avuto alcun aiuto.In un TIFF creare un Sub IFD con miniatura (libtiff)

La mia domanda è, dopo che ho aperto un file di output e ho un TIFF *, ho i miei dati di anteprima tutti pronti per andare (così come i miei dati di immagine principale), come li aggiungo in modo tale che la miniatura è in un sub IFD dell'immagine principale IFD?

risposta

5

Così, dopo aver scavato intorno attraverso il codice sorgente libtiff per un po ', mi sono imbattuto in questo tif_dirwrite.c:

/* 
* 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); 
... 

(ho incluso le informazioni sul copyright perché non ero sicuro se dovessi quando distacco codice dalla libreria qui)

Quindi, per rispondere alla mia domanda (come scrivere una miniatura in una sotto-IFD dell'immagine principale IFD):

//... 
//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); 

Spero che questo aiuta qualcuno e che non devono spendere tanto sforzo quanto ho fatto per capire come farlo. E 'davvero un peccato che il libtiff sia così poco documentato, soprattutto considerando quanto sia ampiamente usato.