これまで自作の関数で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
(2025/03/23 13:45:18時点 楽天市場調べ-詳細)
created by Rinker
¥335
(2025/03/24 08:18:29時点 楽天市場調べ-詳細)
Comments