計算機科学’13 ＃ 2 — マルチメディアと Web 上の描画
久野靖∗

2013.5.28

1

アナログとデジタル再訪

1.1

デジタル化とマルチメディア

アナログとは値が連続的に変化するもの、デジタルとは値が有限個の場合のうちの 1 つという形で表されるもの、という説明は既にしたと思います。では改めて考えてみて、我々の身の回りにある情報は、アナログとデジタルのどちらが多いでしょうか?
答えは「アナログ情報」であるはずです。私達が見たり聞いたり感じたりするものの大きさ、形状、
色合い、音色や音の強さ、重さ、手ざわり、他人の表情や見ぶりなどは、すべてアナログ情報なのですから。
ただし、文字で表された情報だけはデジタル情報です。なぜなら文字とは、かなであれば 50 通り、
漢字を含めても数千通りの場合のうちどれであるかを表すものであり、たとえば「あ」という文字がここに書かれていたとして、それが「あ」と読みとれる限り、どんな形や色であるかということは問題にされないからです。 1
デジタル情報には、コピー、保管、伝送などにおいて劣化しにくいという特徴があります。たとえばコピー機などない昔においては、情報をコピーするのには手で写し取るしかありませんでしたが、文字で書かれた情報 (デジタル情報) であれば文字を書き間違えない限りは写し取ったものも文書としては同じ内容なわけですし、何回書き写しても同様です。これが絵などのアナログ情報では、いかにうまく模写してもオリジナルとは微妙に違うわけですし、模写の模写の模写は本物とはかなり違ってしまうことでしょう。
アナログ

長さをひもで
写し取って
伝えよう！

ひもを
運ぶ…

ひもが
伸びてる！

この棒の
長さを
伝達。

92.2
cm

デジタル

メモを
送る…
電話でも
ＯＫ

ものさしで
長さの値を
読み取ろう！

９２．２ｃｍＯＫ！

図 1: アナログとディジタルによる伝達

経営システム科学専攻
ただし、書体や色などのデザインを鑑賞する場合はやっぱりアナログ情報と言えるでしょう。言葉を聞くのは? 言葉ではその抑揚や調子が重要な情報なので、完全にディジタルとは言いにくいですね。
∗

1

1

保管についても、年を経た古文書であっても、文書ならば文字が何であるか読みとれる限りにおいては同じ文書が復元できますが、色褪せた絵の場合は元がどんな色だったかは推測するしかありません。伝送については、たとえば「手元の鉛筆の長さ」を電話で相手に伝えることを考えてください。
数字を使ってよければ (つまりデジタル情報にしてよければ)、物差しで計ってその数字を読み上げれば簡単です。しかし、もし数字を使わないとすれば、何か手近なものになぞらえる等の方法で伝達したとしても、正確というのは難しいはずです (図 1)。
今日デジタル情報がもてはやされているもう 1 つの理由として、コンピュータで扱えることが挙げられます。従来のアナログ情報であれば、画像ならカメラ、音ならテープレコーダーというふうに、記録や保管にはそれぞれ専用の機器が必要でした。しかしコンピュータは任意のデジタル情報を扱う装置ですから、デジタル化してコンピュータに入れればどのような情報でもまとめて扱えます。一般に、従来からのデジタル情報である文字情報に加えて、画像、動画、音声など複数の種類の情報を一緒に扱うことをマルチメディアと呼びます。そして、コンピュータは単にこれらの情報を記録/再生するだけではなく、プログラムを使ってさまざまに加工したり、ネットワーク経由であちこちに送ったりもできるわけです。コンピュータは見方を変えれば、マルチメディアのための土台 (プラットフォーム) だとも言えるわけです。

1.2

AD 変換と DA 変換

画像や音など、もとがアナログの情報であれば、これらをコンピュータで扱うためにはデジタル情報に直さなければなりません。これを AD 変換 (アナログ=デジタル変換) といいます。そして、これらの情報を人間が鑑賞 (?) するためには、元の形すなわちアナログ情報に戻す必要があります。これを DA 変換 (デジタル=アナログ変換) といいます。そして AD/DA 変換にはそれ固有の限界があることには注意が必要です。
165mm!

16

量子化誤差

図 2: 量子化誤差
たとえば、先の「電話で鉛筆の長さを伝える」例を再考してみましょう。
鉛筆の長さをものさしで計って「165mm」と読み上げたとします。しかし、実際に鉛筆の長さがちょうどミリ単位でぴったり、ということはないでしょう。ですから、実際の長さは 164.5mm〜165.5mmの間のどこかあたり、というくらいしか分かりません。ではノギスで 0.1mm まで計ったら? または
マイクロメータで 0.01mm まで計ったら? そのようにしていくら「単位」を細かくしても、その単位
いくつ分、という形で表す以上、「単位未満」の部分は数値として現れて来ないで無視され、得られた情報が「階段状」になることに変わりはありません。これを量子化誤差 と呼びます。AD 変換において、量子化誤差は本質的に避けられないものです (図 2)。
また、「いつ」計測を行うかという問題もあります。たとえば音のように連続的に変化する信号をデジタル化する場合は、図 3 左のように、連続的に変化するアナログ値に対して一定時間ごとに「測定」を行って値を取得することになります。この「測定する時の値」のことをサンプル値と言います。
とびとびのサンプル値の連なりで変化の様子を表すわけですから、サンプル値を取得する時点と時点

2

入力情報＋サンプリング

出力情報
ＡＤ変換

ＤＡ変換
デジタル
情報
11010...

サンプリングされ量子化されたデジタル値

図 3: AD 変換と DA 変換の間のようすは無視され記録されません。加えて、そのサンプル値をディジタル値として読み取るため、量子化誤差が加わります。
逆に DA 変換においては、「サンプル間隔ごとの」「単位いくつ分で表された」ディジタル情報から元のアナログ情報を復元するので、その「階段」のすき間は適当に埋めることになりますが、図 3 右のように「ギザギザ」が残ってノイズとして知覚されたりすることもあります (デジタル処理された画像などでよく見掛けます)。もちろん、「きざみ」を十分細かくすることで元の情報により忠実にすることはできるのですが、無限に細かくすることはできません。ともかく、このギザギザはサンプリ
ングと量子化による誤差、つまりディジタル化したことにもともとの原因があるわけです。
演習 7-1 2 人 1 組になって、「同じ長さの紙テープにつけた小さい印の位置を、ものさしを使わないで相手に伝達する (伝達には 0 と 1 の並びのみを使う)」という演習を以下から 1 つ以上やってみなさい (a は必ずやるものとする)。

a. 次の方法を試してみなさい。「紙テープを半分に折り、印の位置が左半分にあるなら 0、右半分にあるなら 1 を書く。次に印の入っている側について、また半分に折り、印の位置が左か右かで 0 か 1 を追記する。以上をこれ以上細かく折れなくなるまで繰り返す。できた
0/1 の列を相手に渡し、相手は同じ手順を行うことで印の位置を再現する。」
b. 上とは別の (できればより良いと思う) 方法を 2 人で相談して考案し、実践してみなさい。
c. ものさしを使ってよいことにするが、ただし伝達するのに使えるのは 0/1 の列に限り、なおかつ a で用いた文字数を超えない条件で、方法を考え、実践してみなさい。
「◎」の条件: (1) 小課題 2 つ以上やってあり、 (2) 複数の方式の優劣について適切な (と担当が判断する) 分析・考察がなされていること。

2

サウンド

2.1

サンプル形式のサウンド

マルチメディア情報の具体例として、まずは音 (サウンド) を取り上げることにしましょう。そもそも音とは何でしょうか? 小学校の理科で習ったはずですが、音とは「空気の振動」であり、空気の圧力の変化が連続的に伝わって行くものです。したがって、音の情報を記録しようと思えば、たとえば空気の圧力を電圧などに変換して (これはマイクロフォンが行うお仕事)、その電圧の変化を何らかの形で記録すればよいわけです。逆に、その電圧の変化を空気の圧力に変換すれば、同じ音になって聞こえます (これはもちろんスピーカーのお仕事です)。

3ここまでは空気の圧力に比例する信号、すなわちアナログ信号を考えていましたが、コンピュータで扱うためにはこれをディジタル化する必要があります。その原理については前節で説明しましたが、用語定義も含めて改めて整理して示すと次のようになります。

• アナログ信号から、非常に短い一定の時間間隔でサンプルを採取する。
• 各サンプルは通常、 8 ビットないし 16 ビットの 2 進数として記録する。
この処理を PCM(パルス符号変調)、このような形で記録/表現されている音のことを、サンプル形
式 (ないし PCM 形式) のサウンドと呼びます。ここで、サンプルを取得する間隔のことをサンプリ
ングレート (ないしサンプリング周波数) と言います。たとえば音楽用 CD は 44KHz(1 秒間に 44,000
回) のサンプリングレートを用いています。2 実際にどれくらいのサンプリングレートやビット数が可能かどうか、またその「音質」がどうかということは、コンピュータに接続されているサウンドカー
ド によって決まってきます。今日のできあいの PC などでは、最初からそれなりの音質のサウンドカードが付属していることが多いでしょう。
なお、サンプルのビット数が 8 とか 16 なのは、コンピュータの方でデータがバイト単位だと扱いやすいためです (12 ビットを使う場合もあります)。ここで 8 ビットなら 256 段階、16 ビットなら 65,536
段階の信号の強さが識別できるので、当然ながら 16 ビットの方が高音質になります (CD も 16 ビットを採用しています)。そして、ステレオであれば左右チャンネルごとにサンプルを採取します。
たとえば、 5 分間 (300 秒) の音声を 44KHz、16 ビットステレオでディジタル化するとどれくらいのデータ量になるでしょうか?

300 × 44, 000 × 16 × 2 = 422, 400, 000bitsですから、バイト (8 ビット) 単位に直すと 53 メガバイトくらいになります。ちなみに 6 百万ピクセ
ル (1 ピクセル 24 ビット) のデジカメ画像だとそのまま保存しても 144,000,000 ビットなので音の方がずっと多いですね。サンプリングレートやビット数を減らせばこれを少なくできますが、当然ながら音質は悪くなります。
整理すると、サンプル形式サウンドの場合は、その原理から「きめ細かさ」を次のパラメタによって調節できます。

• サンプリングレート (8KHz〜64KHz くらい)• サンプルのビット数 (8 ビット、12 ビット、16 ビット)• リニア、ノンリニア (目盛りのつけ方を対数的にする)• チャネル数 (モノラル/ステレオ)
以上が基本的なパラメタですが、これを格納するファイル形式として代表的なものに次のものがあります。

• 生の PCM 形式 — 上記のデータを「そのまま」記録したもの• WAV 形式 — 同上だが、ファイルの先頭にサンプリングレート等の情報を記録した部分がついている• QuickTime 形式 — WAV の Apple 版と思えばよい• MP3 形式 — MPEG Layer 3 が正式名称。圧縮を行うことで、生のデータにくらべて大きさが 10 分の 1 くらいにできる。
理論的には、XKHz の音を記録するには 2XKHz のサンプリング周波数があれば十分です。人間の耳に聞こえるもっとも高い音は 20KHz と言われているので、それよりやや高い 22KHz まで記録するために 44KHz というサンプリングレー
トが選ばれたそうです。
2

4

とくに最後の MP3 形式は、これを使えば CD1 枚が 50 メガバイトくらいにできるため、音楽データの配布に広く使われるようになりました。
これは便利なことではありますが、その反面、著作権を無視した音楽データの配布にもつながっていて、その影響による CD の売上減少は音楽産業やそこから収入を得ているアーティストにとって看過できない状態であるとも言われています。このため、著作権管理のための制御機能を追加したファイル形式も提案され使われるようになっています。このような、ディジタル情報の著作権管理のことを一般に DRM(Digital Rights Management) と呼びます。たとえばネットから購入した楽曲は、購入元によってはこのような管理がされていて、自由に手持ちの機器にコピーして聴いたりできないことがあります。
あと 1 つ、ここまではすべて「サンプル形式のサウンド」についての説明でしたが、音を記録する
方式にはもう 1 つ MIDI 形式があります。これは「どんな楽器の」「どんな高さの音を」「いつ」「どれくらいの強さで」「どれくらいの長さ」出すか、という情報を記録する方式で、一見面倒そうに見えますが、音の波を記録するサンプル形式よりずっとコンパクトになりますし、後から (加工ではなく) 編集できます。つまり、楽譜の情報を持っているようなものなので、その楽譜を手直しできるわ
けです。

2.2

サンプル形式サウンドの生成

お話ばかりでは面白くないので、音の話の締めくくりとして、簡単な C プログラムで音を合成して聴いてみることにしましょう。ここではプログラムからは 16 ビット 2 チャンネル 44KHz のデータを生のまま (PCM 形式) で送り出し、これを lame というプログラムで MP3 形式に変換し、続いてmadplay という MP3 再生プログラムで再生して聴くことにします。
とりあえず生成プログラムを示しましょう。配列 a は要素数 2、各要素が 16 ビットの配列で、0 番目が左チャネル、1 番目が右チャネルの音の出力値を保持するのに使います。

/* gensound.c --- generate sound wave */#include <math.h>#include <stdio.h>#define SEC 44000#define D
1.05946309
double t[100];
unsigned short a[2];/* n --- 配列 t の何番目を使うか。 1 つの「音」毎に別の番号に! (0〜99)
hz --- 何 Hz の音を出すか。440 が「ラ」。
vol --- 大きさ、全部の音の vol を合計して最大 15000 に収めること!
pos --- 左右のバランス、 0.5 が中央。 */wave(int n, double hz, double vol, double pos) {double x = sin(t[n] += 2*3.1416*hz/SEC);
a[0] += (int)(vol*pos*x); a[1] += (int)(vol*(1-pos)*x);}main() {int i;
for(i = 0; i < 10*SEC; ++i) { /* 10 秒間 */a[0] = a[1] = 15000;/* 出力配列の初期化 */wave(0, 440, 1000, 0.5);5if(i > 2*SEC) wave(1, 440*D*D*D*D, 1000, 0.2);
if(i > 4*SEC) wave(2, 440*D*D*D*D*D*D*D, 1200, 0.8);
if(i > 6*SEC) wave(3, 880, 800, 0.5);
fwrite(a, sizeof(a), 1, stdout); /* 出力 */}}このプログラムは sin 曲線を持つ音 (正弦波) を同時に 100 音まで重ねて出力できます。それぞれの波は
l = v × p × sinθ, r = v × (1 − p) × sinθにより表されます。 l、r はステレオの左と右の音量、 v は音の大きさ、 p は音の左右のバランス (0.5だと左右が同じ音量) を表します。
ここで角度 θ(単位はラジアンとする) は時間の関数であり、たとえば 440Hz の音 (中央のラ) であ
1
秒につき 2π の割合で変化させる必要があります。このプログラムでは変数 i を 0、1、…とれば 440
変化させながら、各時点での数値を出力して行きます。 i が 1 進む間の時間を 1tick(「きざみ」の意
味) と呼ぶことにすると、サンプリング周波数を 44KHz とした場合、 44,000 は 440 の 100 倍なので2π
θ の変化は 100tick につき 2π 、1tick につき 100ということになります。
ラの音はそれでいいとして、それ以外の音はどうすればいいのでしょうか? 実は (といっても、ご存じの方が多いと思いますが)、音というのは周波数が 2 倍になると 1 オクターブあがって聴こえます。ですから 440 に 2 を掛ければ、1 オクターブ上のラになります。でもその途中の音は…? それは、
1 オクターブの間は半音が 12 個に分けられ、その 1 半音ごとに同じ比率で周波数が上がっていくわ
けですから、3
D×D×D×D×D×D×D×D×D×D×D×D = 2になるような D を計算してやれば、440 に D を 1 回掛ければ半音あがってラ♯、2 回掛ければ 1 音上がってシの音が作れます。実際、そのような D を計算してこのプログラムの冒頭に定義してあります。4
さてプログラムに戻って、1 つの波につき配列 t の 1 つの箱を使って上記 θ を覚えておき、音の周
波数に応じて上の公式を使って θ を増加させて行くことで複数の波を並行して発生させます。
関数 wave は箱の番号、周波数、音量、バランスを受け取って左右チャネルの波の大きさを計算し、a[0] と a[1] に足し込みます (なぜ足し込むかというと、複数の波つまり音を重ね合わせるには足して行く必要があるからです)。
次に main を見てください。ここでは変数 i を 0 から 440, 000 まで順に増やしながら (つまり440, 000tick で 10 秒間)、各 tick ごとの音を生成しています。各 tick ごとに a[0] と a[1] は 15000(中くらいの値) で初期化し、これに wave を使って音の値を重ね合わせていきます。まず、常に 440Hzの音を出し、2 秒後からはその 3 度上、4 秒後からは 5 度上、6 秒後からはオクターブ上の音を増やす
ことで和音をつくり出しています。もちろん、ある秒からある秒までの間だけ音を出したければ

if(i > 2*SEC && i < 3*SEC) wave(...)のようにすればよいわけですが。
最後に、このプログラムの音を聞く手順を説明しておきましょう。

% gcc gensound.c -lm← sin 関数を使う場合は「-lm」指定必要% a.out | lame -rx - - | madplay lame や madplay でなくても、同様のソフトがあれば同じようにして音を聴いてみることができるはずです。
3

ただし平均率の場合。ピアノなどは平均率でチューニングします。

4

ちなみに D = e 12 となります。

ln 2

6

演習 7-2 上のプログラムをコピーしてきてそのまま動かしなさい。うまく動いたら、次の小課題から 1 つ以上 (できれば全部) 選んでやってみなさい。

a. 0 秒から 5 秒未満まで5 440Hz の音、5 秒以上 10 秒までは 880Hz の音を出し、オクターブ上になっていることを確認する。できればさらに、「ドレミファソラシド」を演奏する (最初のドが 0〜1 秒、次のレは 1〜2 秒、というふうにする) となおよいでしょう。
b. 周波数を時間とともに変化させて音を出してみなさい。できれば「ドレミ」「ドミソ」などの音を順番に出すが、移り変わりのところで 1 秒くらいかけて周波数を変化させるとな
およいでしょう。
c. 何か好きな曲を演奏させてみなさい。できれば伴奏か和音がついているとなおよいでしょう。
「◎」の条件: (1) 小課題 2 つ以上がやってあり、(2) 適切な (と担当が考える) 説明・考察が記されていること。

3

グラフィクス

3.1

画像の表現

音に引き続いて、今度は画像 (イメージ) を取り上げましょう。画像を入力する装置の代表はデジタ
ルカメラやスキャナ、画像を出力する装置の代表はディスプレイ (液晶ディスプレイや CRT ディス
プレイ) とプリンタということになるでしょう。ではデジタルカメラやスキャナはどのような形で画像を取り込み、ディスプレイやプリンタはそれをどのようにして復元しているのでしょうか。
まずモノクロ画像から考えてみましょう。音が時間的に連続したものであったのに対し、画像は平面的な広がりを持つ、つまり空間的に連続したものです。これをデジタル化して取り込むためには、
まず平面を縦横のます目に十分細かく区切ります。続いて、それぞれのます目の明るさを電圧や電流に変換する素子を使って取り込み、 AD 変換してディジタル値とします。つまり、画像は縦横に並んだ多数の点の集まりであり、それぞれの点ごとに、ます目の範囲内の元画像の明るさをサンプルした値を持つわけです。なお、この「点」のことをピクセル (pixel) と呼びます。ディスプレイはこの点の集まりを画面に表示し、それぞれのピクセルごとにその値に応じた明るさ/暗さで光らせます。また、プリンタは紙の上にそれぞれの点の集まりを色素を使って定着させますが、ピクセルごとにその値に応じた量の色素を定着させます。そこで、人間がこれらを見ると元の画像 (をデジタル化して復元したもの) が見られるわけです。
デジタルカメラスキャナ

ディスプレイ
プリンタ

デジタル
画像

図 4: デジタル画像の原理
カラー画像の場合も画像がピクセルの集まりであることは同じですが、色の情報を取り込むために、各ピクセルごとに赤 (Red)、緑 (Green)、青 (Blue) の光の 3 原色のフィルタを通して 3 つのサン
プル値を取り込みます。
つまり、各ピクセルは 3 つの値の組 (RGB 値) として表現されます。広く使われているのは、RGB値として各色ごとに 8 ビット (つまり 0〜255 の値) を使い、1 ピクセルあたり 24 ビット (3 バイト) で
5「if(0 <= i && i < 5*SEC) ...」とすればよいです。

7

カラー画像を表す方法です。これを 24 ビットカラーといいます。6 カラーディスプレイは各ピクセルごとに RGB の 3 つの光る点を制御し、それぞれを RGB 値に応じた明るさで光らせますし、プリン
タは各ピクセルごとに 3 色7 の色素を配合して各ピクセルが RGB 値に対応する色になるよう制御し
ます。

3.2

ピクセルグラフィクス

画像は多数のピクセルの集まりですから、画像を加工することは、個々のピクセルごとにその RGB
値を変化させてやることで行えます。また、マウスやタブレットペンなどを使って「お絵描き」をする場合も、描画範囲上でマウスポインタがなぞった部分のピクセルの色を変化させることで「インク」のようにそこの部分の色を変えることができます。
このように、画像を構成するピクセルを直接取り扱うようなグラフィクスの方式を一般にピクセル
グラフィクスと呼びます。ピクセルグラフィクスに基づく作画ソフトのことをペイントソフト (比較的簡単な絵を描く場合に使う) やフォトレタッチソフト (写真などの細密な絵を加工するような場合に使う) と呼びます。代表的なフォトレタッチソフトとしては Photoshop などがあります。
ピクセルグラフィクスに基づく処理には、次のような利点があります。
○ たとえば画面の表示能力目一杯の細かさと色数のデータを作れば、その画面で表せるどんな画面でも表現できる。
○ 「ぼかし」や「にじみ」などの効果を使って中間的な色合いを持った絵や独特のタッチを持った絵が作れる。
その一方で、次のような弱点もあります。
△ ピクセル数を大きくすると (これは絵を大きくする場合だけでなく、点の取り方を細かくする場
合も含まれる)、ファイルも巨大になりやすい。
△ 描いた絵を拡大したり回転するなどの加工に弱く、大きくするとぎざぎざが目立ったりする。
△ ある場所に絵を「描いてしまう」と、そこのピクセルの色を設定してしまうので、後から消したり動かしたりが難しい。(消しゴムで消すというのは結局「背景で塗っている」のと同じ。そして動かすと後が「空白」になる。) 8
いちばん最後の弱点に対しては、画像を複数のレイヤ (層) に分けて扱うことである程度対処可能です。レイヤー機能を持つソフトでは、透明なシート (レイヤ) を複数使ってそれぞれに絵を描き、それを全部重ねて眺めたものが最終的な絵になります。重ねる順番や位置などは描いた後でも変更できま
すし、描き損なった場合はそのレイヤだけ消してやり直せば済むわけです。
ここまではソフトの機能を中心に説明してきましたが、作成した画像は最終的にはファイルに出力します。ピクセルグラフィクスのファイル形式は多数あり、またソフトごとにそのソフトで扱いやすい独自形式を持ったりしますが、共通に使われる代表的なものを挙げておきます。

• BMP(Windows Bitmap) — Windows 固有の、圧縮のないピクセル画像ファイル。あまり使われることはない。
• PBM(Portable Bitmap) — Unix 文化で普及している、圧縮のないピクセル画像ファイル。形式が簡単なので後の実習で使う。
6
先に CSS のところで、色の指定に「rgb(赤, 緑, 青)」という指定を使ったことをご記憶かと思いますが、これも RGB
値を指定していたわけです。
7
正確には、印刷の場合は「真っ黒」を表現するため 4 色目として黒の色素を持たせます。また 3 色も印刷の性質上、シアン、マゼンタ、イエロー (色の三原色) の組合せを使います。
8
ただし、間違って塗った場合には、元の状態を記憶しておくことである程度戻すことは可能。大量には難しい。

8

ピクセルグラフィクス ベクターグラフィクス＝点の集まり＝数式的に表す

図 5: ベクターグラフィクスとピクセルグラフィクス• GIF WWW で最初に使われた圧縮のある画像ファイル形式。色数が最大 256 色という制約があるが、アイコン等には使いやすい。
• JPEG — WWW で GIF に続いて普及した、写真などの画像に適した、損失のある圧縮を主に用いる画像形式。 9• PNG — WWW で最も新しく普及した形式。 GIF の 256 色という制約をなくし、 JPEG と異り損失のない圧縮を用いている。
Web で画像ファイルを使う場合は、最後の 3 つ (GIF、JPEG、PNG) のどれかの形式を使う必要があります (でないと、ブラウザに表示できない)。

3.3

ベクターグラフィクス

ピクセルグラフィクスとは全く違う絵の表し方として、図形などの位置や輪郭を数値的/数式的に覚えておき、絵が必要になる瞬間にその式に応じて絵を生成して表示するという方式があります。このようなモデルを (位置、方向などの「ベクトル」を用いて絵を表すことから) ベクターグラフィク
スと呼びます (図 5)。ベクターグラフィクスでは、絵は円、直線、矩形などの比較的単純な図形の集まりで表すのが普通ですが、高度なソフトになると 3 次曲線、ベジエ曲線などの数式に基づく曲線を活用してもっと柔軟な形を取り扱うこともできます。
ベクターグラフィクスで絵を描くのは、「無限に伸び縮み可能な針金で作った図形にスクリーントー
ンを貼って好きな順に重ねて行く」ようなものだと思えばよいでしょう。針金ですから、あとで自由に置き場所や大きさを調整することができるわけです。ベクターグラフィクスに基づく作画ソフトで代表的なものは Illustrator ですが、より簡便なものはドローソフト、ドローツールと呼ばれます。た
とえば PowerPoint 等の中の作画機能はドローツールになっています。これは、いちど描いた図を後で動かしたりしたいのでドロー系が使われているわけです。
ベクターグラフィクスの得失はだいたいピクセルグラフィクスの裏返しと考えればよいでしょう。
○ 図形の拡大・縮小・回転・重なり順の変更などは単にその変更に基づいて絵を表示し直すだけなのでいくらでも自由に行なえる。
○ 絵は数式的に表されているので、拡大してもぎざぎざになることはない。
○ 絵の情報は座標や形などの情報なので、ファイルの大きさは小さくて済むし、拡大/縮小してもファイルサイズは変わらない。
△ 絵の細かさはソフトに用意されている階調機能や模様機能などで決まってしまい、細かい色合
いは使いにくい。
△ ぼかし、にじみなどの効果は使えない。 10
損失のある圧縮とは、圧縮したものを展開したときに完全に元のデータとは一致しないような圧縮方式をいう。その代わり、圧縮率を高くしやすい。JPEG では圧縮率を指定することで「ファイルサイズが小さいが品質が落ちる」「ファイ
ルサイズが大きいが品質が高い」などの制御ができる。
10
図形を塗りつぶすときに、階調 (グラデーション) や模様 (テクスチャ) などを使うことはできます。
99

ベクターグラフィクスのファイル形式としては、 PostScript があります (TeX の出力に使いましたね)。PostScript はもともとはプリンタで出力するページを記述するための言語であり、手で書くこともできます。現在広く使われている PDF(Portable Document Format) は PostScript の技術を土台に、よりコンパクトになるように設計されていて、印刷形式の文書を配布するのに有用です。このほか、WWW などのページ内容としてベクターグラフィクスを記述できるように設計された言語
として SVG(Scalable Vector Graphics) がありますが、Internet Explorer が SVG に対応していない
ため普及度はいまいちです。このため、現在でも Web 上の画像はピクセルグラフィクスによるものが大部分です。

3.4

RGB 画像を生成する

そろそろお話ばかりだとつまらないでしょうから、今度はプログラムで画像を生成してみましょう。
以下に示すのは「300 × 200 の緑の背景に赤い斜め線が入っている」画像を生成するプログラムです。
生成した画像はファイルに書き出す必要がありますが、ここではなるべくプログラムを簡単にするた
め、PPM 形式の画像ファイルを出力しています。

/* genimage.c --- create color PPM image */#include <stdio.h>#define WIDTH 300#define HEIGHT 200
struct { unsigned char r,g,b; } img[HEIGHT][WIDTH];
main() {makeimage();printf("P6 %d %d 255\n", WIDTH, HEIGHT);
fwrite(img, sizeof(img), 1, stdout);}pset(int x, int y, int r, int g, int b) {if(x >= 0 && x < WIDTH && y >= 0 && y < HEIGHT) {img[y][x].r = r; img[y][x].g = g; img[y][x].b = b;}}makeimage() {int x, y, i;for(x = 0; x < WIDTH; ++x)
for(y = 0; y < HEIGHT; ++y) pset(x, y, 150, 200, 100);for(i = 0; i < 100; ++i) pset(i, i, 255, 0, 0);}}
定数 WIDTH と HEIGHT は画像の幅と高さを表しています。 struct... の行は配列 img の宣言ですが、
buf の 1 要素は r、g、b 各 1 バイトのフィールドから成るレコード型で、それが 200 × 300 並んだ 2次元配列が img なわけです。
main() では、まず makeimage() を呼び出してその中で画像データを設定します。この中は後で自由に直してみてください。それが終わったら、 PPM 形式ファイル用の「ヘッダ行」(画像形式と幅/10高さの情報) を出力し、続いて配列全体を書き出します。PPM 形式の場合、ここにあるように、続いて img の内容をそのまま全部書くだけでよいのです。
pset() は、単に渡された x と y の値が画像の範囲内に入っているかどうかチェックして、OK の時はその位置の img の要素に渡された RGB 値を設定するだけです。このような下請け関数を用意しておくだけで、プログラム本体がずっと見やすくなります。
makeimage() が画像を用意する中心部分です。ここではまず、 x を 0〜WIDTH、y を 0〜HEIGHT の範囲で変化させながら、つまり画像全体を (250, 200, 100) の色に塗りつぶしています。次に i を変化させるループで、(0, 0), (1, 1), . . . (99, 99) の点 (つまり斜めの線上の点) について、色を真っ赤に設定しています。
このプログラムが genimage.c に入っているとして、それを動かすには次のようにしてください。

gcc genimage.ca.out >test.ppm
display test.ppm
このようすを図 6 に示しました。なお、表示用プログラムは display 以外に xv など、PPM 形式を表示できるものなら何でも構いません。

図 6: ビットマップ出力プログラムの結果
このようなプログラムを動かしてみると、画像データというのは単に「RGB 値を山のように並べただけのもの」だというのが納得できると思うのですが、いかがでしょうか。
演習 7-3 画像生成プログラムをまずそのまま動かして生成画像を確認してみなさい。うまく行ったら次の小課題から 1 つ以上 (できれば全部) 選んでやってみなさい。

a. 画像内の好きな位置に縦横とも 100 ピクセルの正方形を塗りつぶしてみなさい。できれば、違う色の正方形が 3 つ重なっているとなおよいでしょう。
b. 画像内に「連続的に色彩が変化する」部分を作ってみなさい。
c. 色のついた地や正方形の上に「半透明な正方形」を描いたものを作ってみなさい。 11「◎」の条件: (1) 小課題 2 つ以上がやってあり、 (2) やった内容の説明や結果の考察が (担当の判断で) きちんと書かれていること。

3.5

PostScript — ベクターグラフィクス記述言語

前述のように、PostScript はベクターグラフィクスのファイル形式ですが、正確には「言語」でもあります。今回は、PostScript ファイルを次のような形で作ります。長さの単位はすべて pt(ポイン1inch) です。
ト、1pt = 72
11

ヒント: 塗る色と既に塗られている色の「平均」を計算してその平均をセットすればよいでしょう。

11

%!PS-Adobe-2.0← PostScript であることを表す%%BoundingBox: 0 0 400 300 ←絵の範囲を表す。今回は 400x300 にした。
…(ここにさまざまな図形記述を入れる)…
showpage←プリンタに送った場合にページを出力する
線を引くには次のコマンドを使います。

• newpath — 新しい線引きを開始する。
• X Y moveto — ペンを指定した座標 (X, Y ) に移動。
• X Y lineto — 座標 (X, Y ) までの線を登録しながら移動。
• stroke — lineto で指定した線引きを一気に実行する。
• W setlinewidth — 線の太さを W pt にする。
では正方形を描くという簡単な例を挙げておきます (図 7)。

%!PS-Adobe-2.0%%BoundingBox: 0 0 400 400
newpath 100 100 moveto 100 200 lineto
200 200 lineto 200 100 lineto 100 100 lineto stroke
showpage

図 7: 正方形を描く
ところで、 PostScript は言語だと書いたのはどういうことでしょう? それは、たとえば「ループ」
を使って先の正方形を繰り返し描いたりできます。同じ場所に描いてもつまらないので、次のコマンドも知っておいてください。

• Tx Ty translate — 絵を描くときの原点を X 軸方向に Tx 、Y 軸方向に Ty だけずらす。
• Sx Sy scale — 絵を描くときの大きさを X 方向に Sx 倍、Y 方向に Sy 倍する。
• D rotate — 絵を描くときの角度を原点のまわりに (反時計回りに)D 度回転する。
繰り返し自体は次のようにします。

• N { 動作列 } repeat — 「動作列」を N 回繰り返す。
では、これを使って正方形を 5 回ずらして描いてみます (図 8)。

%!PS-Adobe-2.0%%BoundingBox: 0 0 400 400
5 {newpath 100 100 moveto 100 200 lineto
200 200 lineto 200 100 lineto 100 100 lineto stroke
30 -15 translate} repeatshowpage12図 8: ループで正方形を描く
最後に、フォント (文字) について説明しましょう。文字を表示するのには、次の 2 つのステップが必要です。

• /フォント名 findfont S scalefont setfont — 指定した名前のフォントを探してきて、サイズ (ポイント数)S に設定し、使用するフォントとしてセットする。
• X Y moveto (文字列) show — 指定位置 (X, Y ) に文字列を表示する。
一度フォントをセットしたら、別のものに変更しないで繰り返し show を使って構いません。文字列を丸かっこで囲んで指定するというのはちょっと変わっていますね。もし文字列の中に丸かっこを入れたければ、「\(」「\)」のようにバックスラッシュを前につけてください。

。
す
で
体
ク
ゴシッ
これは明朝体です。
This is Courier-Bold 12pt.

Times-Roman 36pt.
This is Helvetica 24pt.
図 9: さまざまなフォント
例 (図 9) では「灰色の濃さ」や「色」を変更しているので、その説明もしておきます。

• G setgray — 灰色の明るさ (0.0〜1.0、大きいほど明るい) を設定。
• R G B setrgbcolor — 色を RGB で指定 (どれも 0.0〜1.0、大きいほどその色が強い)。
%!PS-Adobe-2.0%%BoundingBox: 0 0 400 300/Helvetica findfont 24 scalefont setfont
20 20 moveto (This is Helvetica 24pt.) show
/Times-Roman findfont 36 scalefont setfont
20 60 moveto (Times\(-Roman\) 36pt.) show
13

/Courier-Bold findfont 12 scalefont setfont
20 110 moveto (This is Courier-Bold 12pt.) show
0.5 setgray/Ryumin-Light-EUC-H findfont 40 scalefont setfont
20 140 moveto (これは明朝体です。) show
5 rotate 0.8 0.3 0.2 setrgbcolor/GothicBBB-Medium-EUC-H findfont 48 scalefont setfont
20 180 moveto (ゴシック体です。) show
showpage
なお、日本語については必ず EUC コードを使用してください。12 Emacs であれば「Ctrl-X RET f
euc-jp RET」でファイルの文字コードを EUC に設定できます。
ところで、PostScript のフォントはアウトラインフォント、つまり数式で輪郭を表現したフォントを使っていることが特徴で、このため任意のポイント数に大きさを設定できます。今日では他のソフ
トでもこれが普通ですが、PostScript がこれを始める前は、フォントはすべて「ある大きさで」デザインされていたので、自由にさまざまなサイズを指定することはできませんでした。実際にさまざまな大きさにフォントを変更してみてください。
演習 7-4 PostScript の例題を打ち込んで動かしてみなさい。様子が分かったら、以下の小課題から 1
つ以上 (できれば全部) やってみなさい。

a. 簡単な図形を繰り返し表示させて模様を作ってみなさい。
b. 複数サイズの文字や線を組み合わせて自分の名刺を作ってみなさい。
c. 自分が描きたいと思う好きなものを描いてみなさい。
「◎」の条件: (1) 小課題 2 つ以上やってあり、(2) 作成したものの説明や考察が (担当の判断で)きちんと書かれていること。

3.6

LaTeX 文書や Web ページに画像を入れる

画像が作れるようになったので、これを LaTeX 文書や HTML で記述したページに入れる方法を説
明ておきます。

1. TeX に取り込むためには、ファイル形式は Encapsulated PostScript 形式 (%%BoundingBox:の指定された PostScript 形式) でなければなりません。先に作った PostScript の例題は既にそのようにしてありましたね。それ以外の形式のファイルであれば、次のようにして変換できます。
convert test.ppm fig1.ps
また Web ページに入れる場合は、 GIF/JPEG/PNG のどれかに変換する必要があります。

convert test.ppm fig1.png
convert コマンドはファイル名の拡張子部分を見て適切な形式への変換を行なってくれます。13
2. LaTeX では\documentclass と\begin{document}の間に次のような行を追加します。
\usepackage{graphicx}
1213

日本語フォントとして EUC フォントを指定しているためです。
また、PostScript が EPS 形式でない場合は ps2eps コマンドを使うことで EPS 形式に変換することができます。

14

そして本文中の図を入れたい場所に次のようなコマンドを入れます。

\begin{center}\includegraphics[scale=0.5]{fig1.ps}\end{center}
見て分かる通り、「0.5」は縮小比率、「fig1.ps」は PS ファイル名です。scale の倍率の代わりに width=8cm のようにしてでできあがりの幅を指定することもできます (中央そろえはしなくてもいいです)。

3. HTML では次のように画像埋め込みのタグ (img 要素) を使います。
<img src="fig1.ps" alt="サンプル画像">
alt 属性で画像の説明をつけるのは画像が表示できない場合や目の悪い人向けに読み上げソフ
トが読み上げるためなので、意味のある (単なる飾りでない) 画像には必ずつけましょう。
あとはこれまで通りに platex を使ったり、Web サーバに掲載するだけです。LaTeX では platex コ
マンド使用時だけでなく、 xdvi や dvips を使うときも、画像ファイルが同じ場所に置いてある必要があります。HTML では HTML を置いたのと同じ場所に画像ファイルも置いておく必要があります。
演習 7-5 先に作成した画像 (PPM でも PostScript でも) を活用して、次の小課題から 1 つ以上 (できれば全部) やってみなさい。

a. 自分の持っている LaTeX ファイルの中に絵を挿入してみなさい。その上で、どのような形で絵を入れるのが見やすいのか検討・考察しなさい。
b. 自分の持っている HTML ファイルの中に画像を挿入してみなさい。その上で、どのような形で画像を入れるのが見やすいのか検討・考察しなさい。
c. 画像のもう 1 つの入れ方として、背景画像として使う方法があります。それには CSS で次の指定を行います (セレクタは背景を設定する要素。ページ全体に背景を設定したければ
body を指定します)。
セレクタ { background-image: url(ファイル名) }セレクタ { background-repeat: no-repeat/repeat-x/repeat-y/repeat}
上は画像ファイルを指定します。下は敷き詰めかた (1 個だけ/横方向敷き詰め/縦方向敷き詰め) の指定で、指定しないと repeat になります。これを使ってみて、背景画像はどのように使うのがいいか検討・考察しなさい。
「◎」の条件: (1) 小問 2 つ以上やってあり、(2) 作成したものの説明や考察が (担当者から見て)適切であること。

4

3D とアニメーション

4.1

3 次元グラフィクス

ここで少し寄り道して、立体的な描画、つまり 3 次元グラフィクス (3D) についても簡単に説明しておきましょう。14 3D の描画の何が 2D(2 次元グラフィクス、平面的な画像) と違うのでしょうか?
単に 3D といった場合、3D テレビ放送や立体写真のように「立体的に見える (立体視)」という意味も含まれますが、3 次元グラフィクスと言った場合ははコンピュータ内部のデータが 3 次元的であるものを指します。
1415

3D の絵を「絵描きさんが立体的な絵を描くように」ペイントソフトで描くことも不可能ではありま
せんが、手間が掛かってあまりよい方法とは言えません。
そうする代わりに、コンピュータの内部に 3 次元的な物体の形状データを作成し、その形状データ
を特定視点から見た時のようすを計算によって作り出すことで 3D の描画を行うのが普通です。この方法であれば、色あいや視点などを調整したいときには後半の計算だけやり直せば済むという利点があります。
ちなみに、前半の 3 次元の形状データを作り出すことをモデリング、後半の 3D モデルから画像を生成することをレンダリングと言います。前半はたとえばシミュレーションなどの計算で立体空間の様子を作り出すこともできますが、典型的にはモデリングツールと呼ばれる一種のエディタで人間がさまざまな物体の 3D モデルを作成します。
一方、後半のレンダリングには、主要なやり方としては次の 2 つがあります。
• ポリゴンレンダリング — 3 次元の物体の曲面を図 10 のように多面体で一担近似し、その各面ごとに「物体の色」「光源 (太陽やランプなど) と面の角度に応じた反射」などを計算し、その面を画面上に投射した範囲を計算した色で塗る。ただしその後、各面のつながりをスムーズにするよう平均などを取って調整する。
画面

目の位置
この小さい面の色を計算する

画面上で面が占める領域を計算して、先に求めた色で塗る

図 10: ポリゴンレンダリングの原理• 視線追跡 (レイトレーシング、 ray tracing) — 目の位置から画面上の各ピクセルを結んだ線を延長し、3 次元モデルの物体にぶつかる位置を求める。その位置での物体の色合いを求め、さらに物体が「つるつる」なら線を「反射」させてその先へ進む。物体がレンズみたいに「(半) 透明」なら反射光と屈折光の両方を処理する。その結果求めた「色」でそのピクセルを塗る。これを画面上の全ピクセルについて行う (図 11)。
これらを比べると、視線追跡の方が (反射や屈折まで扱うから) ぐっとリアルな絵が作れますが、計算量は膨大になります。一方、ポリゴンレンダリングは多面体近似の荒さによって計算の節約がコントロールできます。最近のグラフィクスワークステーションやゲームマシンでは、この計算を行うための専用ハードウェアを備えていて、これによって高速に 3 次元画像を生成しています。

4.2

動画とアニメーション

ここまではすべて、動かない 1 枚の画像について考えて来ましたが、動画 (ムービー) についても簡単に触れておきましょう。実は動画の原理は非常に簡単で、 (既に多くの人がご存じだと思いますが)1 秒間につき 20 個とか 30 個の画像を取り込み、それらを短い時間間隔で順次表示すれば、絵が動いて見えます (この動画を構成する 1 つひとつの画像のことをフレームと呼びます)。
ここでおもな問題は、1 つの画像ですらそれなりのデータ量になるのに、それを毎秒 20 も取り込
むとデータ量が膨大になるという点にあります。このため、1 つずつのフレームを圧縮して保管した

16

光源
画面

反射光
透明な物体

目の位置

不透明な物体このピクセルの色を決定

それぞれの「出発点」の色を求めて合成

図 11: レイトレーシングの原理
り、連続したいくつかのフレームについて、前のフレームとの差分 (違っている部分) だけを残すな
どの方法で、データ量を圧縮します。その処理を行うのにも 1/20 秒間隔で処理しないと間に合わない (次のフレームが来てしまう) ので、ハードウェア的に処理を行うことが多くなっています。音と同様、動画についても代表的なファイル形式は MPEG、QuickTime、WindowsVideo(WMV) な
ど複数あります。
ここまでは画像を取り込んで動画ファイルにするという話でしたが、画像を生成して動画をつくり出す、つまりコンピュータによるアニメーション生成も多く行われています (この手法で商業映画も作られていますね)。ごく少ない枚数のフレームなら、手で絵を描いてそれをパラパラ漫画のように表示させることでアニメーションさせることもできます。しかしもちろん、1 枚ずつコマンドを指定したり人間が手で描くのでは長いものを作るのはとても大変です。そこで、モデルに基づくアニメー
ションが多く使われます。これは上で説明したモデルに基づく描画の応用編で、コンピュータの内部にモデルを用意して、そのモデルを時間とともに変形させていき、それぞれの時点のモデルから画像を生成することで動画が生成できわけです。この場合、モデルが 3 次元なら 3 次元のアニメーション、
2 次元なら 2 次元のアニメーションということになります。
アニメーションはさらに、実時間的/対話的なものとそうでないものがあります。たとえば、3D モ
デルから高品質な画像を作り出すのはかなりな計算量が必要なので、3 分間の動画を計算するのに数時間の計算を費す、ということもあり得ます。この場合、完成した動画は美しいかも知れませんが、映画のように「鑑賞」するだけで再生時に変化するような点はないわけです。
一方、計算が十分高速である場合 (または計算が追い付く程度まで画像の品質を妥協した場合)、 3
分間の動画の計算が 3 分間より短くて済むことになります。そうなると、画像を「計算しながらその場で上映」でき (実時間アニメーション)、ユーザが何か操作をするとその操作に応じて動画を変化させる (対話的グラフィクス) ことができます。
もちろんこれはテレビゲーム機で行なわれていることであって、今や珍しいことでもなんともありませんが、その「計算を追い付かせる」ためにさまざまなハードウェア上/ソフトウェア上の工夫がなされています。15

5

canvas 要素による Web 上の描画

5.1

Web の発展と HTML5

ここまで、Web ページの記述は今日の標準である HTML4.01 に基づいて説明してきましたが、この「先」についても簡単にお話しておきます。まず、HTML などの標準を取りまとめている W3C(WWWPlayStation(初代) が出るまでは対話的 3 次元グラフィクスは極めて限られた人にしか体験できませんでした。コン
シュマー技術恐るべし。
15

17

Consortium) では HTML ではタグの種類が固定であるためさまざまな用途に対応できないとうい問
題を克服するため、タグを自由に定義できる汎用的なマークアップ言語 XML(eXtensible Markup
Language) を制定し、これが広く使われるようになりました。XML が HTML と違っている主要なこととして、次のものが挙げられます。
• タグ名は必ず小文字で書くこととし、属性値は必ず「"…"」で囲むこととした。
• 中身のある要素のタグは「<x>…</x>」のように必ず対で書き、閉じタグの省略は許さないこととした。逆に中身のないタグは「<x />」のようにそれ単独であることを示す形とした。
• 名前空間機能により、複数の XML に基づく言語を混在させられるようにした。
XML は現在では、情報システムのさまざまな分野でさまざまな情報を記述する言語として普及しています。
W3C では XML の普及を受けて HTML も XML に移行することを計画し、まず HTML 4.01 をおおよそそのまま XML の形に合わせた XHTML 1.0 を制定しました。 XHTML 1.0 は HTML 4.01 とさほど違わないのでそれなりに使われています。
しかしその後、W3C は引き続きより XML 色の強くなった XHTML 1.1、XHTML 2.0 を推進しようとしましたが、各ブラウザベンダーなどはこれまでと互換性がなく、機能としてはあまり魅力的でなかったこれらの標準には否定的で、実装する主要ブラウザが現れないまま年月が経過しました。
その中で、2004 年に Opera、Mozilla、Apple が WHATWG(Web Hypertext Applicaiton Technology Working Group) を構成し、後方互換性がありながらマルチメディアなど魅力的な機能も含まれる HTML の後継仕様を検討するようになりました。
このような状況を見て、W3C も 2007 年にこの WHATWG の方向性を共有することにして、その考え方に基づき HTML5 を策定することとなりました。HTML5 では HTML 4.01 に足りなかった意
味的なマークアップを強化するとともに、音声、ビデオ、図形などをこれまでより簡単に取り込める機能も追加した仕様を策定しています。
これでめでたしめでたしならいいのですが、WHATWG と W3C で協力すると言っていながら、実際に作業をすると立場の食い違いが大きくなり、現在は HTML5 でも WHATWG の推進する living
standard 版と W3C が標準化を行う版で分裂しているという状態です。また、HTML5 のブラウザへの実装は個々のブラウザやプラットフォームごとにばらばらという状況で、1 つの HTML ファイルでさまざまな環境に対応するという理想はなかなか達成されそうにありません。
そのような状況なのですが、HTML5 の中でもブラウザ上で JavaScript を使って自由に描画するという機能を提供する canvas 要素は、比較的早くから実装されてきて、多くのブラウザで利用可能ですので、最後にこれについて取り上げます。

5.2

canvas 要素

SVG が W3C で標準化された XML に基づくグラフィクスの記述言語であるのに対し、canvas
は WHATWG で取りまとめられ、「ブラウザ上で簡単に絵を描く」機能を提供しています。以前はJavaScript でブラウザ画面の中のさまざまな要素を操作する (消したり動かしたりする) ことはできても、「絵を描く」ことはできず、そのような機能がとても求められた結果作られた、という感じです。こちらも Web ページへの入れ方から見てみましょう (とりあえず四角を 1 個描いています)。
<!DOCTYPE html><html><head><title>canvas example</title><script type="text/javascript">var ctx;
18

function init() {ctx = document.getElementById(’c0’).getContext(’2d’);
ctx.fillStyle = ’rgb(200,220,255)’;
ctx.fillRect(20, 20, 80, 60);}</script></head><body onload="init()"><canvas id="c0" width="400" height="300">(canvas 未対応)</canvas></body></html>canvas 要素の中身は、その HTML を表示したブラウザが canvas に対応していない場合に表示されます。つまり、対応していない時は「対応していない」と知らせるために内側の内容を使うわけです。では対応している時はどうするかというと、JavaScript プログラムでその中身をすべて描画します。ここではページがロードされ終ったら init() という関数を呼び出し、その中ですべての処理を行っています。その最初に必要なのは、 HTML 中の canvas オブジェクトを document.getElementById()で取得し、続いて canvas に描画するためのコンテキストオブジェクトを getContext(’2d’) で取得することです (現在は種別としては 2 次元グラフィクスを表す「2d」しか使えません)。
この後はすべて、このコンテキストオブジェクトに対するメソッド呼び出しやプロパティ設定でス
タイルの設定や描画を行います。その中身はここまでに PostScript で見て来たのとよく似ています。
図形を描くメソッドは次のものがあります。
• fillRect(X, Y , W , H)、strokeRect(X, Y , W , H)、clearRect(X, Y , W , H) —長方形の領域を塗る (ないし、輪郭を描く、ないし領域をクリアする)• fillText(文字列, X, Y ) — 文字列を描画• beginPath()、moveTo(X, Y )、lineTo(X, Y )、arc(X, Y , R, D1 , D2 , B)、closePath()、stroke()、fill() — PostScript の同名のものと同様。arc については円弧の中心の XY 座標、
半径、開始点と終了点の角度 (ラジアン)、 true か false かで描く向き (右廻りか左廻り) を指定
します• drawImage(IM G, X, Y )、drawImage(IM G, X, Y , W , H) — 画像を描く (後者では幅と高さを指定することで引き延ばしや縮小も可能)
画像は通常のブラウザ上の画像オブジェクトを指定します (たとえば img 要素を取って来るなど)。画像が描けることからも分かるように、canvas はベクターグラフィクスではなく、単に「任意の絵が描けるような API(呼び出しインタフェース)」なわけです。
図形等を描く際のスタイルの設定はプロパティの代入で行います。一方、座標変換はメソッドで指定し、PostScript 等と同様です。

• fillStyle、strokeStyle、lineWidth、globalAlpha — 塗りつぶしの色、線の色、線の幅、
描画全体の透明度を設定16• font — 文字のサイズとフォントを「’20px Times New Roman’」などのように指定• translate(X, Y )、rotate(R)、scale(Sx, Sy ) — 移動、回転、拡大縮小• save()、restore() — 描画状態全体をスタックに保存し、またスタックから復元
そのほか個々の色も、rgba(R,G,B,A) という書き方で A のところに 0.0〜1.0 の値を設定することで透明度のある色が指定可能です。
16

19

図 12: canvas による描画の例
このほか、ゲームやユーザによるお絵描きを行うためにはマウスイベント等を扱う必要があります
が、こちらは通常のブラウザのイベント機構を使います。上の例をさらに直して、画面上をクリックするとその場所に円が現れるようにしてみました (図 12)。

<!DOCTYPE html><html><head><title>canvas example</title><script type="text/javascript">var ctx;function init() {ctx = document.getElementById(’c0’).getContext(’2d’);
ctx.fillStyle = ’rgb(200,220,255)’;
ctx.fillRect(20, 20, 80, 60);
addEventListener(’mousedown’, mousedown, false);}function mousedown(evt) {ctx.fillStyle = ’rgb(255,0,0)’;ctx.beginPath();ctx.arc(evt.layerX, evt.layerY, 10, 0, Math.PI*2, true);
ctx.fill();}</script></head><body onload="init()"><canvas id="c0" width="400" height="300")(canva 未対応)</canvas></body></html>
演習 7-6 canvas の例題をそのまま動かして確認しなさい。うまく動いたら、以下の課題から 1 つ以
上 (できれば全部) やってみなさい。

a. 自分の知っているどこかの国旗を描いてみなさい。できれば、マウスボタンを押すと色が変わるようになっているとなおよいでしょう20

b. 最後の例題の「mousedown」を「mousemove」に取り替えると絵が描けるようになるが、ボタンを押さないままでも描き続けるのでつながった線になってしまう。
「mouseup」「mousedown」「mousemove」の 3 つを併用して、普通のお絵描きソフトのように押している間だ
け描けるようにしてみなさい。できれば、単色でなく複数色が使えるとなおよいでしょう(押すごとに色が切り替わるとかでもよいです)。
c. 関数 init() の末尾に次のような文を入れると、指定した関数が 50 ミリ秒に 1 回呼ばれるようになる (関数名は好きに決めてよい)。
setInterval(関数名, 50);
これを利用して時間とともに変化する絵を表示してみなさい。色と位置 (ないし形) の変化が両方あるとなおよいでしょう。
「◎」の条件: (1) 小問 2 つ以上やってあり、 (2) いずれもやったことの説明および考察が (担当の判断で) 適切であること。

6

まとめ

この章の前半では、アナログとデジタルの違いについて改めて考え、続いて私達の身のまわりにある代表的なアナログ情報である音や画像のデジタル化やコンピュータ内部での表現方法についてその原理を中心に見てきました。絵や音がコンピュータ上でどのようにして扱われているのか感じがつか
めたかと思います。引続き後半では、前回学んだ HTML と CSS の機能を土台として、実際のサイトを作るプロセスと、ページ設計のやりかた、レイアウトのつけかたについて取り上げました。

21