Hatena::ブログ(Diary)

はっぴー☆ちゃんねる

2007-10-30

[][]libtiffマニュアル 18:12

あまりよい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に変更しています。)

f:id:hoshimi_etoile:20071030181234j:image

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