これまで自作の関数でMulti TIFFファイルを書いたり、読んだりしていたのですが、libtiffライブラリを使ってみることにしました。
私が使うデータは主に8bit、16bitのグレースケールです。
今回は16bit(unsigned short int)グレースケールsingle TIFFの読み込みです。
Windows、Linuxで解析を行うので、両方でコンパイルできるようにしています。
その他
・確認のためにprintfでヘッダ情報を標準出力に表示しています。そのため、テキストファイルエディタなどで「read-16bit.txt」に含まれる余分なヘッダ情報を削除しておきます。
・ImageJで「read-16bit.txt」を「File」→「Import」→「Text Image」で「read-16bit.txt」を選択する。
ソース
環境によっては「nodefaultlib」を付けなくてもコンパイルは通ります。
標準出力に出力したデータには、先頭に読み取ったTIFFヘッダ情報が含まれるので、削除してからImageJで読み込みます。
#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
int main( int argc, char **argv )
{
int i, j;
int width, height;
uint32 tifsize;
uint16 samplesperpixel, bitspersample;
uint16 photometric, fillorder, compression;
uint16 orientation, resunit, planarconfig;
uint16 *buf, *line;
TIFF *tif;
tif = TIFFOpen("test-16bit.tif", "r");
if ( tif == NULL )
{
printf("ERROR: Can not open tiff file \n");
exit( EXIT_FAILURE );
}
// 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 != 16 )
{
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 ( 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];
}
}
_TIFFfree( line );
TIFFClose( tif );
// 画像情報を標準出力する
for( i = 0; i < height; i++ )
{
for( j = 0; j < width; j++ )
{
if ( j == width - 1 )
{
printf("%d", buf[width * i + j]);
}
else
{
printf("%d ", buf[width * i + j]);
}
}
printf("\n");
}
free( buf );
return EXIT_SUCCESS;
}
created by Rinker
¥3,960
(2026/01/08 14:31:35時点 楽天市場調べ-詳細)
created by Rinker
¥295
(2026/01/08 14:31:35時点 楽天市場調べ-詳細)


Comments