Chapter2. 画像を扱う

[—ATOC—] 1 [—AUTO_SECTION_NUMBER—] 1

画像を扱う

本実験ではレイトレーシング法によって画像を生成するが,そのためには当然ながら何らかの画像形式を扱う必要がある.

C言語には基本的な入出力機能やメモリ管理,文字列操作,数学関数,などを提供する標準ライブラリが用意されているが, これらに画像を扱うものは含まれていない.

通常,C言語によるプログラムで画像を扱うには,そのためのライブラリを用意する必要があるが,本実験では簡単のため テキストで記述可能な簡便な画像形式であるPPM形式を用いる.

PPM形式について

PPM形式はNetpbmというツールキットで扱う画像形式の一つである.

Netpbmは主に画像にフィルタ処理を施したり,様々な画像形式(JPEG, PNG, GIF, etc..)を相互に変換することを 目的として作られたツール群で,PPM形式はそれら画像形式の中間形式の一つである.

PPM形式の画像ファイルは全てプレーンテキストで記述することが出来る

PPM形式は以下のような構造を持っている.

  1. マジックナンバー”P3″
  2. 画像の幅と高さ
  3. 色深度
  4. 画像データ(RGB色値のシーケンス)

以下はPPM形式の例である.

P3             # "P3"はマジックナンバー
# "#"記号から改行まではコメントとして無視される
3 2            # 画像の幅と高さ
255            # 色深度
# ここから下は画像データ
255    0    0
  0  255    0
  0    0  255
255  255    0   
255  255  255
  0    0    0

【確認】 上記のテキストをエディタで入力して保存し,以下のコマンドで表示させよ. (ここでは”simple.ppm”というファイル名で保存している.)

$ display -sample 10000% simple.ppm
(※ ダラーマーク’$’を打ち込む必要はない.ダラーマークはコマンドライン端末のプロンプトを表している.)

図1ような画像が表示されることを確認せよ.

シンプルなPPM画像
図1. 表示結果

このコマンド(display)を終了する際は,qキーを押すかウィンドウの閉じる(×)ボタンを押下する.

※ 上述の画像は幅3ピクセル,高さ2ピクセルときわめて小さい画像なので上記のコマンドでは10倍の大きさに拡大して表示させている.”-sample 1000%”の指定は常に必須というわけではない(以後は使用しない).

画像データの格納方向

プログラムで画像を扱う場合は,画像データそのものは一次元の配列としてメモリに格納する場合が多い.

その際の,メモリ上のレイアウトはいろいろな場合があるが,たいていは画像の一行(1ピクセル行)を上から順番つなぎ合わせたレイアウトを用いる場合が多い.

図2にその例を示す.

画像は一次元
図2. 一次元配列としての画像データ

PPM形式もこの習慣に倣っている.PPM形式ではひとつの画素を3つの数値の組として表現し,画像データ全体は画素データの一次元の配列として表現されている. この関係を図3に示す.

PPM形式のテキストと画像の対応
図3. PPM形式のテキストと画像の対応

課題 [—EXCLUDE—]

課題1-1 最初のプログラム

(作業時間目安:5分)

幅512,高さ512のPPM形式の画像を生成するプログラムを作成せよ.

画素値は全て(r,g,b)=(255,127,64)で塗りつぶすこと.

ソースファイル名はfill.cとする.

以下のプログラムを穴埋めせよ.

リスト1. fill.cの穴埋め #include #define WIDTH 512 #define HEIGHT 512 int main() { int y,x; unsigned char r,g,b; printf(“P3\n”); /* マジックナンバー */ printf(“%d %d\n”, WIDTH, HEIGHT); /* 幅と高さ */ printf(“255\n”); /* 色深度 */ for(y = 0; y < HEIGHT; ++y) { for(x = 0; x < WIDTH; ++x) { /* 【この部分を埋める】 */ }/* for */ }/* for */ return 0; } [/c]

生成画像は図4のようになる.

fill.cの生成画像
図4. fill.cの生成画像

プログラムのビルド方法および実行方法

以下のコマンドでプログラムの実行形式を生成する.

$ gcc -std=c89 -Wall fill.c -o fill

以下断りがない場合,生成する実行形式の名前はソースファイル名から拡張子.cを除いたものとする.

問題なくビルドできたら,以下のコマンドでPPM形式画像を生成し表示する.

$ ./fill > fill.ppm $ display fill.ppm
(※ ダラーマーク’$’を打ち込む必要はない.ダラーマークはコマンドライン端末のプロンプトを表している.)

課題1-2 単純なグラデーション

(作業時間目安:5分)

幅512,高さ512のPPM形式の画像を生成するプログラムを作成せよ.

この画像はX方向に従って黒から白へのグラデーションをもつ.

ソースファイル名はgradation1.cとする.

生成画像は図5のようになる.

gradation1.cの生成画像
図5. gradation1.cの生成画像

ヒント:座標値の範囲[0,511]を,一端[0.0,1.0]にマップする.

プログラムのビルド方法および実行方法

以下のコマンドでプログラムの実行形式を生成する.

$ gcc -std=c89 -Wall gradation1.c -o gradation1

以下断りがない場合,生成する実行形式の名前はソースファイル名から拡張子.cを除いたものとする.

問題なくビルドできたら,以下のコマンドでPPM形式画像を生成し表示する.

$ ./gradation1 > gradation1.ppm $ display gradation1.ppm
(※ ダラーマーク’$’を打ち込む必要はない.ダラーマークはコマンドライン端末のプロンプトを表している.)

課題1-3 RGBチャネルごとのグラデーション

(作業時間目安:10分)

幅512,高さ512のPPM形式の画像を生成するプログラムを作成せよ.

ソースファイル名はgradation2.cとする.

この画像はRGBの各チャネルごとに以下のようなグラデーションを持つ.

  • Rチャネル:X方向に従って255から0に変化する
  • Gチャネル:Y方向に従って0から255に変化する
  • Bチャネル:座標(0,0)のとき0,座標(511,511)のとき255となる.

生成画像は図6のようになる.

gradation2.cの生成画像
図6. gradation2.cの生成画像

ヒント:BチャネルはX座標とY座標の積

プログラムのビルド方法および実行方法

以下のコマンドでプログラムの実行形式を生成する.

$ gcc -std=c89 -Wall gradation2.c -o gradation2

以下断りがない場合,生成する実行形式の名前はソースファイル名から拡張子.cを除いたものとする.

問題なくビルドできたら,以下のコマンドでPPM形式画像を生成し表示する.

$ ./gradation2 > gradation2.ppm $ display gradation2.ppm
(※ ダラーマーク’$’を打ち込む必要はない.ダラーマークはコマンドライン端末のプロンプトを表している.)

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>