Logo address

スクリーンショットの撮り方

目次

2004/09/28
スクリーンやウインドウの画像を撮りたいのだけどどうしたらよいの?
との質問を受けました。
Plan 9 はこのような問題をとても面白い方法で、そう、Plan 9 らしい方法で処理しています。それを紹介しましょう。

ビューア

まずは画像のビューアである page から紹介します。
page は実際には PS ファイルや PDF なども読み取りかなり守備範囲が広い。マニュアルには general purpose document viewer と書かれている。(詳しくはマニュアルを参照してください。)

page には多くのオプションがあるが、普通はオプションなしの

	page ファイル ...
の形で使用する。ファイルは複数指定できる。
実行すると画像が表示され、左ボタンで画像を動かし、右ボタンでファイルを選択し、中央のボタンを押すと次のようなメニューが出る。
{page} を実行し中央のボタンを押した時のメニュー

スクリーンの画像

スクリーンの画像は仮想ファイルとして
	/dev/screen
に置かれています。
	page /dev/screen
を実行しているとその事が確認できます。

ウインドウの画像(1)

同様にウインドウの画像は
	/dev/window
であるが
	page /dev/window
を実行しても何も見えないはずです。(なぜでしょう?)
	cp /dev/window /tmp/a
	page /tmp/a
を実行してみれば、ヒントがつかめます。(今度は /tmp/apage を実行する直前のウインドウの様子が画像ファイルとして記録されているのが確認されます。)

ウインドウの画像(2)

我々がウインドウの内容を画像ファイルとして記録したい場合には、たいていの場合、そのウインドウの中でコマンドを投入するわけには行きません。従って他のウインドウから目的のウインドウの内容をコピーすることになります。

	/dev/wsys
の下にはスクリーン上の全てのウインドウ情報が置かれています。
各ウインドウには ID が付けられており、その ID は
	cat /dev/winid
で確認できます。数字が表示されますが、ウインドウごとに異なる数字を表示するのが確認されるでしょう。
	ls /dev/wsys
を実行すると全てのウインドウの ID が表示されます。N を ID とします。
	ls /dev/wsys/N
を実行すると ID が N のウインドウに関する情報を収めたいろいろなファイルがあることが分かります。これらはもちろん仮想ファイルです。
term% ls /dev/wsys/1
--rw------- M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/cons
---w------- M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/consctl
--rw------- M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/cursor
---w------- M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/kbdin
--rw------- M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/label
--rw------- M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/mouse
--r-------- M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/screen
--rw------- M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/snarf
--r-------- M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/text
--rw------- M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/wctl
--rw------- M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/wdir
--r-------- M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/window
--r-------- M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/winid
--r-------- M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/winname
d-r-x------ M 20 arisawa arisawa 0 Sep 29 08:47 /dev/wsys/1/wsys
/dev/wsys/1/windowが ID が 1 のウインドウの画像です。実際他のウインドウから
	page /dev/wsys/1/window
を実行してみるとそのことが確認されます。

PNG ファイルへの変換

画像を収めた仮想ファイルの形式は Plan 9 による独自形式です。これを PNG 形式に変換するには (生成するファイルを /tmp/1.png とすれば)
	topng /dev/wsys/1/window > /tmp/1.png
を実行します。
topng で生成した PNG ファイルを page が読み取れない事があります。page は内部で png を使用しており、png に問題があると思えます。その場合でも topng によって生成されたファイルは Mac OSX では正しく読み取れています。

PNG ファイルへの変換の他に GIF ファイルへ変換する事もできます。マニュアル jpg(1) を参照してください。残念ながら JPEG ファイルへの変換ツールは無いようです。

ウインドウの特定

多数のウインドウがあるときに、目標とするウインドウの ID を特定する必要があります。ウインドウの重なり順序情報を利用できれば目標とするウインドウがすぐに分かるのですが、Plan 9 のウインドウマネージャーである rio はどういうわけか、その情報をユーザに提供しません。(もちろん rio の内部ではその情報を持っているはずです。) その事が例えば acme を複数個開いたときに plumping が全ての acme で発生するなどの問題の原因になっています。
rio の現在の仕様ではウインドウを特定するのに
	/dev/wsys/*/label
が役に立つでしょう。この内容を読めば、そこで実行中のプログラムの名前が分かります。例えば acme のウインドウは
	grep acme /dev/wsys/*/label
で分かります。

セルフタイマー

時には、セルフタイマーを使用してウインドウのコピーをとりたい事もあります。このページの最初の画面は
	grep page /dev/wsys/*/label
でウインドウ ID を調べ (例えば 3 とします)
	sleep 10; topng /dev/wsys/3/window >/tmp/a.png
で得られたものです。