
Thread
2012.11.23 23:49 "Re: [Tiff] Write Exif data to Tiff file", by Paul Heckbert
DonM-2 wrote:
>
> I would like to write Exif data (such as exposure time) to a tiff file I > am creating. Is this possible with libtiff,...
>
Yes, it's possible. Here's a sample C++ program that does it. This code works with libtiff version 4.0.3.
wtiff.cpp
---
// write a test picture to a TIFF file using libtiff, setting some optional EXIF tags
#include <assert.h>
#include <tiffio.h>
#include <tif_dir.h> // libtiff internals; for TIFFFieldArray
typedef unsigned char uint8;
int main() {
int nx = 640, ny = 480;
char *filename = "t.tif"; // file to write
TIFF *tif = TIFFOpen(filename, "w");
assert(tif);
assert(TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, nx) != 0);
assert(TIFFSetField(tif, TIFFTAG_IMAGELENGTH, ny) != 0);
assert(TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8) != 0);
assert(TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB) != 0);
assert(TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, ny/2) != 0); // two big
strips
assert(TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW) != 0);
assert(TIFFSetField(tif, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL) != 0);
assert(TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT) != 0);
assert(TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG) != 0);
assert(TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3) != 0);
// add EXIF tags to the set of tags that libtiff knows about
// necessary if we want to set EXIFTAG_DATETIMEORIGINAL, for example
const TIFFFieldArray *exif_fields = _TIFFGetExifFields();
_TIFFMergeFields(tif, exif_fields->fields, exif_fields->count);
// the following two tags are optional
assert(TIFFSetField(tif, TIFFTAG_SOFTWARE, "WhizBang 1.2.3") != 0);
assert(TIFFSetField(tif, EXIFTAG_DATETIMEORIGINAL, "2011:08:01 18:28:47")
!= 0);
// the following line is optional. it causes IFD to be written at
beginning of file.
// otherwise it would be written at end of file (after the pixels)
assert(TIFFCheckpointDirectory(tif) != 0);
uint8 *buf = (uint8 *)_TIFFmalloc(nx*3);
assert(buf);
picture has horizontal ramp in red, vertical ramp in green //
for (int y=0; y<ny; y++) {
uint8 *p = buf;
for (int x=0; x<nx; x++) {
*p++ = x*255/(nx-1); // r
*p++ = y*255/(ny-1); // g
*p++ = 0; // b
}
assert(TIFFWriteScanline(tif, buf, y, 0) != -1);
}
_TIFFfree(buf);
TIFFClose(tif);
}
---
Here's a makefile fragment for Mac OSX or Linux that takes care of providing the include path to the tif_dir.h file, which is not part of the build, but is in the libtiff source directory $TIFFSRC.
TOP = whatever
TIFF = $(TOP)/tiff-4.0.3/build
TIFFSRC = $(TOP)/tiff-4.0.3/libtiff
.cpp.o:
g++ -c $(COPTS) -I$(TIFF)/include -I$(TIFFSRC) $<
If your version of libtiff is older, try the following small changes to the source code, which work with version 3.8.2, at least:
replace #include <tif_dir.h> line with
extern "C" { extern const TIFFFieldInfo *_TIFFGetExifFieldInfo(size_t *);
}
and replace the two lines that call _TIFFGetExifFields and _TIFFMergeFields with these three lines:
size_t exif_field_count;
const TIFFFieldInfo *exif_field_info =
_TIFFGetExifFieldInfo(&exif_field_count);
TIFFMergeFieldInfo(tif, exif_field_info, exif_field_count);
If you work in C and not C++, it would not be difficult to translate the above code to C.
--
View this message in context: http://old.nabble.com/Write-Exif-data-to-Tiff-file-tp32482486p34716158.html
Sent from the Tiff / LibTiff mailing list archive at Nabble.com.