1週目(2):ポインタの配列

【復習】

ポインタの復習

【課題】

サンプルプログラム2は,ppm(Portable Pixel Map)形式の画像ファイル(バイナリファイル)を入力とし,画像を90度回転した後,別のファイルにppm形式で出力する処理を行う.

作業課題

  1. ex4_2という名前で新規プロジェクト(Win32 Console Application)を作成し, サンプルプログラム2に用意されている5つのファイルmain.c, img_io.h, img_io.c, img_proc.h, img_proc.c をプロジェクトに追加しなさい.(ツールバーのプロジェクト(P)→既存項目の追加(A)で追加できる.)プロジェクトをビルドし,コンパイルエラーがないことを確認しなさい.
  2. サンプル画像img01.ppmというファイル名で,先ほど作成したプロジェクトex4_2のDebugフォルダの下に保存しなさい.
  3. 画像ビューア IrfanView (スタート→プログラム→IrfanView→IrfanView3.98)を起動し,ウィンドウ内にサンプル画像をドラッグ&ドロップして画像を表示してみなさい.
  4. コマンドプロンプトで,Debugフォルダの下に移動し,"ex4_2.exe img01.ppm result.ppm"と入力し,プログラムを実行してもプロジェクトex4_2の下に出力ファイルresult.ppmができていないことを確認しなさい.(画像ファイルを出力する処理が未完成なので出力されない.
> Z:
> cd (各自のディレクトリ)\ex4_2\Debug
> ex4_2.exe img01.ppm result.ppm

解説

(1)ディジタル画像データの基礎

コンピュータで処理可能なディジタル画像とは画素 (Pixel) と呼ばれる点の集合である.画素は図1のように二次元格子状に配置され,(横方向の画素数)×(縦方向の画素数)画素の画像と呼ばれる.下図は 16×8画素の画像の例である.


ディジタル画像の一部の概念図(16×8画素の画像の例)

さらに各画素は明るさや色によって特徴付けられる.明るさは,最も明るい状態と真っ暗な状態を何段階で表現するかによって何階調と呼ばれる.色は,赤(R)緑(G)青(B)の光の三原色の混合比で表す.例えば,”白”はを1:1:1の明るさ比で混合したもののうち,最も明るい色である.同じ混合比でも,明るさを変えることによって白〜灰〜黒を表現することができる.三原色の明るさがすべて0の場合が黒である.(※注1)



(2)raw形式

raw形式(RGB汎用形式)は単純に画像のRGBデータのみをそのまま記録している.しかし書き出すソフトや機種によりRGBデータを記録する順序が異なる場合がある.代表的なパターンは「ピクセル毎」「色プレーン毎」の2種類である.下図は,ピクセル毎にRGBを記録している例である.この図では,画素値を2桁の16進数で表している.RGB各8ビットの場合,RGBの各値の最大値はFF(=10進数で255),最小値は00(=10進数で0)になる.



(3)ppm形式

PPMはPortable Pixel Mapの略称である.ピクセル毎に記録されたrawファイルの先頭に,画像のサイズなどを表すヘッダ情報がついた形式になっている.

PPMには,画像データが「アスキー形式」の文字列で表されているものと,「バイナリ形式」で表されているものの2種類がある.データがアスキー形式かバイナリ形式かはヘッダーの先頭2バイト(マジックナンバー)で判別する.バイナリ形式の場合のマジックナンバーはP6である.

横幅と縦幅,最大輝度,コメントなどのヘッダー情報はバイナリではなく文字列となっている.先頭の文字が#(シャープ)の場合,改行コード(0x0A)まで「コメント」とみなされる.

PPMは「最大輝度」を指定することにより24ビットフルカラー画像だけでなく48ビットカラーなどにも対応できるようになっている.



■バイナリ形式のppmのフォーマット

  長さ 内容
ヘッダー 2バイト
1バイト
不定
不定
不定
1バイト
不定
1バイト
P6
改行コード
横幅を示すアスキー文字列
セパレーター(空白)
縦幅を示すアスキー文字列
改行コード
最大輝度を表すアスキー文字列
改行コード
データ 不定
不定
輝度を示す値(バイナリ)
輝度を示す値(バイナリ)

■ サンプル画像 img01.ppm のファイルの中身をバイナリエディタで覗いてみると…

 


参考文献

David C. Kay, John R. Levine著,'' グラフィックファイルフォーマットハンドブック,'' アスキー出版局, 1995.