はじめに
これまで自作の関数で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
(2025/02/09 16:45:08時点 楽天市場調べ-詳細)
created by Rinker
¥335
(2025/02/10 08:32:51時点 楽天市場調べ-詳細)
Comments