step02 2Dグラフィクスの基礎

2Dは2次元(2-Dimention)の略。つまり2Dグラフィックスは平面上に表示される画像という意味である。PCの画面は平面なんだから、2Dなのはあたりまえじゃないかと思うかもしれないが、PCでは、画面の奥行き方向にも空間が広がっているような、立体的な画像表現(3Dグラフィックス)も可能なので、それと区別してこの名前で呼ぶ。
2Dグラフィックスは単一の技術ではなく、図2-1に示すような、多くの要素技術の集合体である。この講座ですべてを扱う余裕はないが、基本的な手法をマスターするだけでも、自分の作るアプリに華やかさと説得力が備わるだろう。

図2-1: 2Dグラフィックスの関連要素技術

2種類の「2Dグラフィックス」

普段PC上で表示したり編集している「絵」に、2つの異なる種類が混在していることにお気づきだろうか。2Dグラフィックスには大別して、

の2系統があるのだ。以下の各節で順に解説しよう。

ラスターグラフィックス

デジカメ写真やアニメ絵のように、単一の色をもつ画素(pixel)という微少な長方形を、平面上にタイル状に敷き詰めた形式の画像をラスターグラフィックスという。たとえばこの講義資料のタイトルの背景に使われている画像(プログラミングの荒野を旅するキャラバン)がそれである。同じ面積の画像であれば、画素のサイズが小さいほど解像度が高いといわれる。ラスター画像は、後述のベクター画像に比べて、一般に多くの記憶容量を占める。

演習:ラスター画像の情報量

デジタル化されたラスター画像の情報量を計算してみよう。

画素の色
フルカラーと呼ばれる、RGB各色256階調で表現された(単一の)色は、何Byteのデータか? 各色1024階調ならどうか?
静止画像
フルハイビジョン(横1920ドット×縦1080ドット)の静止画像は、何Byteのデータか? 4K(横3840ドット×縦2160ドット)ならどうか?
ヒント:画素(pixel)の数と、単一色のデータ量の積で表現される。

ベクターグラフィックス

ペンで線を描き、ブラシで色を塗るというように、点、線、面などの図形を組み合わせて作る画像をベクターグラフィックスという。たとえばこのstepの図2-1に使われている画像(2Dグラフィックスの関連要素技術)がそれである。
PCにはお絵かきソフトと呼ばれる一連のアプリケーションがあるが、これらも画像表現の種類に応じて2分類される。

ドロー系アプリ
ベクターグラフィックスを作成・編集するアプリ。たとえばAdobe Illustratorや、Microsoft WordやExcel、PowerPointの「図形描画」機能が、これに分類される。
ペイント系アプリ
ラスターグラフィックスを作成・編集するアプリ。たとえばAdobe Photoshopや、WindowsのユーティリティであるPaintが、これに分類される。
ベクター画像の構成要素はだが、幾何学的な概念としての、大きさを持たない点幅を持たない線とは異なる。最終的にPCの画面上に表示される時には、やはりラスター画像の「画素」に変換されるのである。
2Dグラフィックスでは、点の座標は(x, y)の2つのパラメータで表現される※1が、たとえば図2-2に示す楕円は、それを囲む長方形(矩形)の左上と右下の座標という4つのパラメータにより定義される。くり返しになるが、(x, y)で表現されるのは幾何学的な「点」ではなく、微少な長方形である「画素」である。たとえば、(0, 0, 100, 100)という4つのパラメータで表現される長方形があるとき、点(100, 100)は、楕円の外部にあるのはもちろん、それを囲む長方形の外部にある。

1 PCにおける座標系は、数学のそれと異なり、表示画面(たとえば後述するキャンバス)の左上を(0, 0)とし、x軸は右方向が正、y軸は下方向が正となる。つまり図2-2においてx1 > x0, y1 > y0である。

図2-2: 平面座標と図形の位置関係

アニメーション

2種類の画像表現について理解したところで、つぎの要素技術を、プログラムを書きながら身につけよう。
ゲームのキャラクター(登場人物※2)は、ラスター形式で描かれることが多い。それを時間とともに変化させ、動画として見せるのがアニメーションという手法である。ただし、映画のような本物の動画ではなく、パラパラ漫画のように絵を1コマずつ更新表示したり、画像の表示位置を移動することによって、動きを表現している。たとえば2枚1組の画像を交互に表示しながら位置を移動すれば、キャラクターが歩いているように見えるわけである。

2 ICTでは、"A"とか"漢"などの文字も「キャラクター」と呼ばれるので、ちょっとややこしい。

それでは、2枚の画像を用いて、簡単なアニメーションを作ってみよう。
まず、大きなラスター画像を背景として表示する。画像ファイルの形式は、windowsで最も一般的な.bmpフォーマットである。プログラムをリスト2-1に示す。


リスト2-1: anime1.pyw

まず、ウィンドウ上に、画像や図形を表示するためのキャンバスウィジェットを配置する。つぎに画像オブジェクトを作成するのだが、実はここにtkinterモジュールの欠点があり、一般的な.bmp、.png、.jpgなどの画像フォーマットに対応していない※3。そこで、現状ではPILという別モジュールの助けを借りて画像表示を実現するしかない。
anime1.pywの実行画面を図2-3に示す。

3 現状で対応しているのは、なぜか.xbm(モノクロ)、.gif、.pgm、.ppm(以上カラー)と、マイナーな画像フォーマットばかりである。強く改善を望むところ。

図2-3: 背景画像を表示する

つぎに、背景画像にキャラクターの画像を重ねて表示し、表示更新用のループ中で表示位置の座標を変化させれば、簡単なアニメーションが表示できる(リスト2-2)。


リスト2-2: anime2.pyw

cvs.create_image()によって、キャンバスウィジェット上に表示できるImageオブジェクトが変数glに作られている。ループはその位置を変化させるためのもので、1回毎に、

という処理が行われている。
anime2.pywの実行画面を図2-4に示す。この動きは、2Dグラフィックスではおなじみのもので、ゲームアプリにおける壁に反射するボールなどに応用できる。
また、キャラクターの周囲にまで背景画像が回り込むように表示されているのは、キャラクターの画像ファイル(girl.png)に対し透明化処理が行われているからである。透明色※4には、「黒」が指定されている。透明化処理は、画像透過ツールなどのWebサイトを利用して行うのが簡単である(「ペイント3D」など、ペイント系アプリにも透明化機能を持つものがある。「ペイント」では透明化はできない)。

4 自己矛盾に満ちた表現だが、ICTの中の人は、特に違和感を感じない(=感覚がマヒしている)。処理系によって透明と見なされる単一色のこと。

図2-4: 簡単なアニメーション表示

透明化処理の効果

リスト2-2において、キャラクターの画像ファイルを"girl_org.png"に入れ替えて、アニメ表示がどのように変わるか確認しよう。この画像ファイルには、透明化処理を行っていない。
つぎに、上記「画像透過ツール」のサイトで、ファイルに透明化処理を行い、ふたたび表示の変化を確認すること。

さまざまな図形の描画

tkinterモジュールのキャンバスウィジェットは、何種類かのベクター図形を表示できる機能を持っているので、キャンバスに図形を表示するだけなら、簡単なプログラム(リスト2-3)で実現できる。図形ごとのオプション引数(名前付き引数)の意味については、tkinterのリファレンスマニュアルを参照すること。


リスト2-3: drawshapes.pyw

drawshapes.pywの実行画面を図2-5に示す。
ただしこれでは、単にキャンバス上に「絵」を描いたというだけであり、これらを動かしてゲームを作るとか、複雑な処理をさせようとしても、ちょっと手が出せない。プログラムが複雑すぎて、自分で管理できなくなると予想できるからだ。つまり、この辺が従来の構造化パラダイムであるモジュールと関数の限界らしいのである。
では、どうしたらよいのか? このことを踏まえ、つぎのstepでは、GUIプログラムを構成する多種多様な要素をモノとそのふるまいに注目して整理する新しい構造化パラダイム、クラスとオブジェクトについて学ぶ。新たな手法で構造化することで、画面上のに過ぎなかったものが、画面の中に実在するモノとして意識されてくる不思議さを体験してもらいたい。

図2-5: 簡単なアニメーション表示