-
Notifications
You must be signed in to change notification settings - Fork 126
Open
Description
Hi :)
I've been trying out libtiff.net and it's been working great so far.
I would like to write a tiled TIFF image with multiples pages and subIFDs, are SubIFDs writing supported? I haven't found any such example online, and all my attempts resulted in a corrupted output file where the first 4 bytes do not correspond to a tiff file.
Here's the code I'm working with, could you point me towards anything wrong?
static void Main()
{
const string path = @"path\to\output\file.tiff";
const int tileSize = 256;
using Tiff tiffFile = Tiff.Open(path, "w");
// Base IFD (full resolution)
int baseW = 1024;
int baseH = 1024;
SetCommonTags(tiffFile, baseW, baseH, tileSize);
tiffFile.SetField(TiffTag.SUBFILETYPE, FileType.PAGE);
int subCount = 2;
int[] subOffsets = new int[subCount]; // placeholders (all zeros)
tiffFile.SetField(TiffTag.SUBIFD, (short)subCount, subOffsets);
WriteAllBlackTiles(tiffFile, baseW, baseH, tileSize);
tiffFile.WriteDirectory();
// SubIDFs (reduced resolutions)
int w2 = baseW, h2 = baseH;
for (int i = 0; i < subCount; i++)
{
// next reduced size
w2 = Math.Max(1, w2 / 2);
h2 = Math.Max(1, h2 / 2);
tiffFile.CreateDirectory();
SetCommonTags(tiffFile, w2, h2, tileSize);
tiffFile.SetField(TiffTag.SUBFILETYPE, FileType.REDUCEDIMAGE);
WriteAllBlackTiles(tiffFile, w2, h2, tileSize);
tiffFile.WriteDirectory();
}
}
static void SetCommonTags(Tiff t, int width, int height, int tile)
{
t.SetField(TiffTag.IMAGEWIDTH, width);
t.SetField(TiffTag.IMAGELENGTH, height);
t.SetField(TiffTag.SAMPLESPERPIXEL, 1);
t.SetField(TiffTag.BITSPERSAMPLE, 8);
t.SetField(TiffTag.SAMPLEFORMAT, SampleFormat.UINT);
t.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK);
t.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
t.SetField(TiffTag.COMPRESSION, Compression.LZW);
t.SetField(TiffTag.ORIENTATION, Orientation.TOPLEFT);
// tiled layout
t.SetField(TiffTag.TILEWIDTH, tile);
t.SetField(TiffTag.TILELENGTH, tile);
// (optional) resolution metadata
t.SetField(TiffTag.XRESOLUTION, 72.0);
t.SetField(TiffTag.YRESOLUTION, 72.0);
t.SetField(TiffTag.RESOLUTIONUNIT, ResUnit.INCH);
}
static void WriteAllBlackTiles(Tiff t, int width, int height, int tile)
{
// 8-bit black tile
byte[] buf = new byte[tile * tile];
for (int y = 0; y < height; y += tile)
{
for (int x = 0; x < width; x += tile)
{
int tileIndex = t.ComputeTile(x, y, 0, 0);
int written = t.WriteEncodedTile(tileIndex, buf, buf.Length);
}
}
}
Metadata
Metadata
Assignees
Labels
No labels