例題8-1:覗き窓をあける

B:

A: どうした、B君。難しい顔をして。

B: いや、細かい作業をしていたら肩がこっちゃって…。

A: 細かい作業?

B: いや、本で読んだ「窓問題」っていうのを見てみたいと思って、アニメーションを作成しているんですが、一コマずつ線をずらしていくのが大変で。

../_images/08-1-01.png

A: えー。そんな面倒くさいことやってんのか。pythonでやりゃいいじゃん。

B: でも、丸い穴が空いた刺激ってVisionEgg.MoreStimuliにはありませんよね。四角い穴なら長方形を組み合わせて作れますけど、丸い穴って作れないんじゃないですか。

A: 例題6で言っただろ。複雑な刺激を作るときにはTextureを使えばいいんだよ。穴の部分が透明なテクスチャを作ればいい。

B: 透明なテクスチャ?

A: ん? B君はHTMLを使ったwebページの作成はある程度知ってるみたいだから、GIFやPNG画像に透明度を指定できるのは知ってると思っていたのだが。

B: ああ、透過GIFとか透過PNGですね。こういう奴。

../_images/08-1-02.png

A: そうそう、それと同じことで、透明度を指定したテクスチャを作ってやれば、丸でもなんでも自由に穴をあけることができる。

B: へぇ。じゃあ今作ってたアニメーションの画像をそのまま背景を透明にして保存すれば出来そうですね。じゃあ早速。

../_images/08-1-03.png

A: ええと、このサンプル画面に出ているのはWindowsのCorelDraw X3での保存例で、オブジェクトからマスクを作成してマスクを透明色に指定しています。 PNGで保存する場合は後で困るのでインタレースにはしないでくださいね。

B: Aさん、誰に話してるんですか。

A: いや、ちょっとな。そうそう、世間はPhotoShop派の人が多いかも知れませんがPhotoShopは多分膨大な解説ページがあると思うので検索してくださいね。 GIMPとか使ってる人は言われなくても自分で検索しちゃうだろうからこれまた省略。

B: またいいかげんな…。

A: いいんだよ。もっときちんとした人が書いた解説を読んでもらった方が。さて、画像は保存できたかい?

B: Aさんがぶつぶつ言ってる間にとっくに出来ていますが。

A: よし。じゃあそいつを読み込んで背後で棒を動かすプログラムを書くか。例題6-1のプログラムをベースにしたらすぐ書けると思うよ。よいしょ。

  • 行番号なしのソースファイルをダウンロード→ 08-1.py

  • 画像ファイルをダウンロード→ 08-1.png

 1#!/usr/bin/env python
 2# -*- coding: shift-jis -*-
 3
 4from VisionEgg import *
 5from VisionEgg.Core import *
 6from pygame import *
 7from VisionEgg.MoreStimuli import FilledCircle
 8
 9import VisionEgg.Textures
10
11
12from math import sin, cos, pi
13
14import OpenGL.GL
15
16screen = get_default_screen()
17screen.parameters.bgcolor = (0.0,0.0,0.0)
18SX,SY= screen.size
19
20tex = VisionEgg.Textures.Texture('08-1.png')
21stimWindow = VisionEgg.Textures.TextureStimulus(
22                       texture = tex, size = tex.size,
23                       anchor='center', position=(SX/2,SY/2),
24                       internal_format=OpenGL.GL.GL_RGBA)
25
26stimBar = VisionEgg.MoreStimuli.Target2D(
27                       size = (200,5),
28                       color = (0.0, 1.0, 0.0),
29                       anchor = 'center',
30                       orientation = 45,
31                       position = (SX/2,SY/2))
32
33
34stimList = [stimBar,stimWindow]
35
36viewport = Viewport(screen=screen, stimuli=stimList)
37
38startTime = VisionEgg.time_func()
39t = VisionEgg.time_func()
40while t-startTime < 5.0:
41    t = VisionEgg.time_func()
42    stimBar.parameters.position = (SX/2+100*sin(t-startTime),SY/2)
43    event.get()
44    screen.clear()
45    viewport.draw()
46    swap_buffers()

B: ずいぶんあっさり出来ましたね。

A: だろ。ポイントはたったひとつ。24行目のVisionEgg.Textrues.TextureStimulusに与えているinternal_formatパラメータだ。 ここにαチャンネルもちゃんと考慮してねと指定すればそれだけでOK。

B: αチャンネル? それにOpenGL.GLっていうのは…

A: αチャンネルというのはRGBが赤、緑、青の成分をあらわすように、各ピクセルの透明度をあらわす成分だ。0ならば完全な透明、 最大値ならば完全な不透明となる。

B: 最大値? 1.0ですか?

A: あー。VisionEggの中では1.0だが、255を使う場合とか、いろいろある。それは次回のネタにとっておこうと思っていたのだが。

B: あ、そうですか。じゃあその時に改めて聞きます。

A: そうしてくれ。それとあとOpenGL.GLか。これは、VisionEggの内部ではOpenGLというライブラリを使っていて、OpenGLの形式で画像のフォーマットを 指定してやらにゃいかんのだ。で、OpenGL.GLというモジュールにその形式が定義されているので、14行目でOpenGL.GLをimportして24行目でGL_RGBAという形式を指定している。

B: 他にどういう形式があるんですか?

A: αチャンネルを指定しないGL_RGBとかだな。興味があればOpenGLについて検索しなさい。多分心理実験ではGL_RGBとGL_RGBAを知っていれば困ることはないはず。

B: ふうん。

A: あと、注意するべきは34行目のリストの順番かな。stimBarをstimWindowの前に書いておかないと、丸い窓の背後を通ってくれない。 さて、実行してみるか。

../_images/08-1-04.png

B: おおお。一コマずつ作っていた僕の苦労は一体…。

A: ちなみに24行目の指定を省略すると、αチャンネルが考慮されなくなってしまう。そうするとこんな風になってしまう。

../_images/08-1-05.png

B: うわ。ええっと、これって背後で緑色の棒が動いているんですよね?

A: ちゃんと動いてるぞ。見えないけどな。疑うなら27行目を書き換えて棒の長さをうんと長くしてみたまえ。すぐ出来るから。

B: どれどれ…。おお、確かに。

../_images/08-1-06.png

A: 透明度を指定する必要がないときは、internal_formatは省略してしまって何も問題ない。さて、これでαチャンネルを指定したテクスチャの読み込みはOKかな。 次回はテクスチャをファイルから読み込むのではなくプログラム内で直接「描く」方法にを解説するぞ。

B: へ? そんなこと出来るんですか?

A: もちろん。今回省略したαチャンネルの値についても解説するぞ。