はじめに
これまで自作の関数でMulti TIFFファイルを書いたり、読んだりしていたのですが、libtiffライブラリを使ってみることにしました。
私が使うデータは主に8bit、16bitのグレースケールです。
今回は16bit(unsigned short int)グレースケールMulti TIFFの読み込みです。
読み込んだMulti TIFFファイルをSingle TIFFファイルにバラしています。
Single TIFFファイルの書き込みは以前の記事を流用しています。
ImageJなどを使えばMultiTIFFをバラしたり、作成したり出来ますが、プログラムを作っていると自前で行う場面も多いため、メモしておきます。
Windows、Linuxで解析を行うので、両方でコンパイルできるようにしています。
コンパイルの方法は「libtiffの環境構築」を参照。
ソース
環境によっては「nodefaultlib」を付けなくてもコンパイルは通ります。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __GNUC__
#include <tiffio.h>
#endif
#ifdef _WIN32
#include "tiffio.h"
#ifdef _DEBUG
#pragma comment(linker, "/nodefaultlib:\"libcmtd.lib\"")
#else
#pragma comment(linker, "/nodefaultlib:\"libcmt.lib\"")
#endif
#pragma comment(lib, "libtiff.lib")
#endif
// 16bit TIFF
#define BIT_COUNT 16
int tiff_count_directory( TIFF * );
void tiff_write( uint16 *, int, int, int );
int main( int argc, char **argv )
{
int i, j, k;
int width, height;
uint32 tifsize;
uint16 samplesperpixel, bitspersample;
uint16 photometric, fillorder, compression;
uint16 orientation, resunit, planarconfig;
uint16 *buf, *line; // unsigned shrot int
TIFF *tif;
int dircount;
tif = TIFFOpen("hoge-16bit-multi.tif", "r");
if ( tif == NULL )
{
printf("ERROR: Can not open tiff file \n");
exit( EXIT_FAILURE );
}
// MultiTIFFのDirectory数を取得する
dircount = TIFFNumberOfDirectories( tif );
// dircount = tiff_count_directory( tif );
printf("TIFF Directories: %d \n", dircount);
// return EXIT_SUCCESS;
// Tagを読み込む
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
TIFFGetField(tif, TIFFTAG_FILLORDER, &fillorder);
TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation);
TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
// 確認
printf("width: %d \n", width);
printf("height: %d \n", height);
printf("bitspersample: %d \n", bitspersample);
printf("samplesperpixel: %d \n", samplesperpixel);
printf("compression: %d \n", compression);
printf("photometric: %d \n", photometric);
printf("fillorder: %d \n", fillorder);
printf("planarconfig: %d \n", planarconfig);
printf("resunit: %d \n", resunit);
// Error Check
if ( width <= 0 || height <= 0 )
{
printf("ERROR: width or height is error \n");
exit( EXIT_FAILURE );
}
if ( samplesperpixel != 1 )
{
printf("ERROR: Only samples/pixel = 1 \n");
exit( EXIT_FAILURE );
}
if ( bitspersample != BIT_COUNT )
{
printf("ERROR: Only 16-bit samples \n");
exit( EXIT_FAILURE );
}
// 画像の領域確保
tifsize = width * height * sizeof( uint16 );
buf = ( uint16 * )malloc( tifsize );
if ( buf == NULL )
{
printf("ERROR: Can not get memory [buf] \n");
exit( EXIT_FAILURE );
}
// 画像1ライン分の領域確保
line = ( uint16 * )_TIFFmalloc( TIFFScanlineSize( tif ) );
// line = ( uint16 * )_TIFFmalloc( width * 1 * sizeof( uint16 ) );
if ( line == NULL )
{
printf("ERROR: Can not get memory [line] \n");
exit( EXIT_FAILURE );
}
// 画像情報を読み込む・書き込む
for ( k = 0; k < dircount; k++ )
{
if ( ! TIFFSetDirectory( tif, k ) )
{
printf("ERROR: Can not set TIFF directory [TIFFSetDirectory] \n");
exit( EXIT_FAILURE );
}
for ( i = 0; i < height; i++ )
{
if ( TIFFReadScanline( tif, line, i, 0 ) < 0 )
{
printf("ERROR: Can not get TIFF line [TIFFReadScanline] \n");
exit( EXIT_FAILURE );
}
for ( j = 0; j < width; j++ )
{
buf[width * i + j] = line[j];
}
}
tiff_write( buf, width, height, k );
}
_TIFFfree( line );
TIFFClose( tif );
free( buf );
return EXIT_SUCCESS;
}
//
// TIFFのDirectory数を数える
//
int tiff_count_directory( TIFF *tif )
{
int cnt = 0;
do
{
cnt++;
} while ( TIFFReadDirectory( tif ) );
return cnt;
}
//
// single TIFFファイルを保存する
//
void tiff_write( uint16 *buf, int width, int height, int k )
{
char fname[FILENAME_MAX];
char tiftitle[FILENAME_MAX] = { '\0' };
uint16 samplesperpixel, bitspersample;
uint32 tifsize;
double resolution;
TIFF *tif;
resolution = 72.0;
bitspersample = BIT_COUNT;
samplesperpixel = 1;
// 画像データの保存
sprintf( fname, "%s_%03d.tif", "out", k );
tif = TIFFOpen( fname, "w" );
if ( tif == NULL )
{
printf("ERROR: Can not open tiff file \n");
exit( EXIT_FAILURE );
}
strcpy(tiftitle, "Test program");
tifsize = width * height * sizeof( uint16 );
TIFFSetField(tif, TIFFTAG_SOFTWARE, tiftitle);
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
TIFFSetField(tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(tif, TIFFTAG_XRESOLUTION, resolution);
TIFFSetField(tif, TIFFTAG_YRESOLUTION, resolution);
TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
TIFFWriteEncodedStrip(tif, 0, buf, tifsize);
TIFFClose( tif );
}
created by Rinker
¥3,960
(2026/01/31 06:44:09時点 楽天市場調べ-詳細)
created by Rinker
¥295
(2026/01/31 16:08:39時点 楽天市場調べ-詳細)

Comments