libtiffマニュアル

あまりよいlibtiffのマニュアルが無かったので自分で作りました。*1一応自分用のメモ。。。

libtiffマニュアル

libtiffはTIFFファイルを読み込んだり書き込んだりするライブラリです。
公式サイトはhttp://www.libtiff.org/。日本語のサイトだとIBMhttp://www.ibm.com/developerworks/jp/linux/library/l-libtiff/が参考になると思われます。

TIFF形式の参考にhttp://www.snap-tck.com/room03/c02/cg/cg05_01.html。このドキュメントの参考にさせていただきました。

libtiffのソースは
FTP::: ftp://ftp.remotesensing.org/pub/libtiff/
HTTP:: http://dl.maptools.org/dl/libtiff/
にあります。

ドキュメントは http://www.libtiff.org/document.htmlにあります。(英語です。)

以下の使い方はVisualStudio2005を前提にしております。

使い方

libtiff.libにリンクをはる

libtiff.libはソースディレクトリのルートにおきます。(そうでない場合はリンクの指定にパスを書きます)
libtiff.libにリンクを張ります。([ソリューションエクスプローラ]-[(プロジェクト名)]のプロパティから[構成プロパティ]-[リンカ]-[入力]で[追加の依存ファイル]にlibtiff.libを追加する。)

tiffio.h,tiff.hを読み込む

適切な場所にヘッダファイルを置き、includeします。私の場合はソースのルートディレクトリにlibtiffディレクトリを作りその中におきました。

libc.libを無視する

これは理由は分からないのですがlibc.libが何たらかんたら…というエラーが出ます。
[プロジェクト]-[プロパティ]でプロジェクトのプロパティページを開き[構成プロパティ]-[リンカ]-[入力]-[特定のライブラリの無視]にlibc.libを追加。これでコンパイルは通るはずです。

ファイルを書き出す場合

0:あらかじめ画像のソースを作っておく。
今回はcharの配列で実装してみましょう。以下は斜めグラデーションです。

 char* buffer = (char*)malloc( width * height * sizeof(char));
 for(unsigned i =0;i<width;i++){
   for(unsigned j=0;j<height;j++){
     buffer[j*width + i] = (i+j)%255;
   }
 }

1:まずTIFFファイルを開きます。

TIFF* image = TIFFOpen("output.tif", "w"));

2:ファイルヘッダの設定を行います。
2-1:ImageWidth
画像の横のピクセル数です。

 TIFFSetField(image, TIFFTAG_IMAGEWIDTH, width);

2-2:ImageLength
画像の縦のピクセル数です。

 TIFFSetField(image, TIFFTAG_IMAGELENGTH, height);

2-3:BitsPerSample
1ピクセルごとに何bitのデータを割り当てるかを指定します。
白黒二色の場合は1bitなので1。グレースケールやRGBの場合は8bitなので8と指定します。

 TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 8);				

2-4:SamplePerPixel
グレースケールの場合はgrayのみなので1。RGBカラーの場合はR,G,B三色なので3を指定します。

 TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, 1);

2-5:Compression
圧縮形式を指定します。

COMPRESS_NONE…非圧縮
COMPRESSION_CCITTRLE…ITU-T(旧CCITT、国際電信電話諮問委員会)Group3 1次元変形ハフマン・ランレングス・エンコーディング
COMPRESSION_CCITTFAX3…ファクシミリ互換のITU-T Group3
COMPRESSION_CCITTFAX4…ファクシミリ互換のITU-T Group4
COMPRESSION_LZW…固定長コードLZW圧縮
COMPRESSION_OJPEG…JPEG(Joint Photographic Experts Group)圧縮
COMPRESSION_JPEG…JPEG圧縮−2

ここでは特に圧縮する必要がないので(最近のTIFFって圧縮しないもんなんじゃないの?)COMPRESS_NONEを指定します。

 TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_NONE);			

2-6:Photometoric
色の変化の指定をします。
PHOTOMETRIC_MINISWHITE…グレースケールで、値が0のとき白になります。
PHOTOMETRIC_MINISBLACK…グレースケールで、値が0のとき黒になります。
PHOTOMETRIC_RGB…RGBカラーです。(0,0,0)で黒になります。

 TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);

2-7:FillOrder
ビットマップイメージデータにおけるビットの保存順
FILLORDER_MSB2LSB…上位ビット→下位ビットの順で保存されます。
FILLORDER_MSB2MSB…下位ビット→上位ビットの順で保存されます。

 TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);

2-8:PlanarConfig
SamplesPerPixesが2以上の場合に、ビットマップイメージデータがピクセル優先モードで保存されているか、それともプレーン優先モードで保存されているかを表すコード。
普通はPLANARCONFIG_CONFIG。

 TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);

2-9:Orientation
原点の場所を指定。
普通は画像の原点は左上に置くので、ORIENTATION_TOPLEFT。

TIFFSetField(image, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);

2-10:XResolution YResolution
pixels/resolution in x。実寸のサイズと画面上のサイズの比を指定。いわゆるdpi。画面上に出力する場合、普通は72dpi。(印刷時は300dpiくらい?)

 TIFFSetField(image, TIFFTAG_XRESOLUTION, 72.0);
 TIFFSetField(image, TIFFTAG_YRESOLUTION, 72.0);

2-11:ResolutionUnit
// Resolution上の単位。
RESUNIT_NONE…単位なし
RESOLUTION_INCH…インチ
RESOLUTION_CENTIMETER…センチメートル。
ここは日本なので(?)RESUNIT_CENTIMETER。

 TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_CENTIMETER);

2-12:SOFTWARE
出力したソフトウェア名。ここではLibTiffTestとしておく。

 TIFFSetField(image, TIFFTAG_SOFTWARE, "LibTiffTest");				

3:ファイルに書き出す。

 TIFFWriteEncodedStrip(image, 0, buffer, width * height);

imageはTIFFファイルポインタ。二つ目はstripの値。0にしておきます。bufferは画像ソースのポインタ。最後がその画像のピクセル数になります。

4:TIFFファイルのポインタを解放。
メモリの解放は忘れずに。

 TIFFClose(image);

サンプルプログラム

斜めグラデーションを表示するサンプルを用意しました。

 /**
  * @file libtiffTest
  * @brief libtiffのサンプルプログラム。
  * @author HOSHIMI'S WORKS
  * @since 2007/10/30
  */

 #include "stdafx.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 #include "libtiff\tiffio.h"
 
 #pragma comment(lib,"libtiff.lib")
 
 int main(int argc, char *argv[]){
 	unsigned width = 400;
 	unsigned height = 320;
 
 	//画像ファイルのソースの作成(斜めグラデーション)
 	char* buffer = (char*)malloc( width * height * sizeof(char));
 	for(unsigned i =0;i<width;i++){
 		for(unsigned j=0;j<height;j++){
 			buffer[j*width + i] = (i+j)%255;
 		}
 	}
 	TIFF *image;
 
 	// TIFFファイルを開く
 	if((image = TIFFOpen("output.tif", "w")) == NULL){
 		printf("Could not open output.tif for writing\n");
 		return 1;
 	}
 
 	 // We need to set some values for basic tags before we can add any data
 	TIFFSetField(image, TIFFTAG_IMAGEWIDTH, width);						// width
 	TIFFSetField(image, TIFFTAG_IMAGELENGTH, height);					// height
 	TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 8);						// (0〜255の場合は8)
 	TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, 1);					// GrayScaleの場合は1。RGBの場合は3
 	TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_NONE);			// 圧縮形式。
 	TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);	 // 0->白:PHOTOMETRIC_MINISWHITE 0:->黒:PHOTOMETRIC_MINISBLACK RGB:PHOTOMETRIC_RGB
 	TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);		 	// ビットマップイメージデータにおけるビットの保存順
 	TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);		 // 普通はこれでよし。
 	TIFFSetField(image, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);		 // 原点をどこに置くか。普通は左上。
 	TIFFSetField(image, TIFFTAG_XRESOLUTION, 72.0);				 		// pixels/resolution in x 印刷上の長さとピクセルの比
 	TIFFSetField(image, TIFFTAG_YRESOLUTION, 72.0);				 		// 画面上で扱う場合は通常72。
 	TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_CENTIMETER);	 // Resolution上の単位。RESUNIT_NONE RESOLUTION_INCH
 
 	TIFFSetField(image, TIFFTAG_SOFTWARE, "LibTiffTest");			 	// 出力したソフトウェア
  
 	//ファイルに書き出します
 	TIFFWriteEncodedStrip(image, 0, buffer, width * height);
 
 	//TIFFファイルのメモリを解放します。
 	TIFFClose(image);
 
 	free(buffer);
 }

出力結果。(ここでは出力結果をjpgに変更しています。)

*1:ここではしんとえてぃはおやすみです。。。