ここでは,実習で画像の読込,加工,保存をするために利用するライブラリgfcについて説明します. ライブラリ(library)とは,プログラムでよく利用される機能を集めたプログラムの部品です. ライブラリを読みこむことで,自分で作成するプログラムで, ライブラリが提供する機能を利用することができます. gfcライブラリは,Gfcクラスを提供します.
以下では,例題を用いて,Gfcの利用法を一通り説明します. また,別ページにGfcのリファレンスマニュアルを用意しています. Gfcクラスが提供する機能一覧については,そちらを参照して下さい.
なおgfcは,この実習用に独自に作成したライブラリです. Rubyの標準的なパッケージには含まれていません. 作り込みが甘いところもあるかと思いますので,バグ(欠陥)があったら,教えて下さい. また,新しい機能を追加してほしいという希望があれば挙げて下さい. 必要度に応じて,対処を考えたいと思います.
もくじ
- 例題
- プログラムの仕様
- プログラム
- require --- ライブラリの読み込み
- Gfcによる画像の読み込み
- Gfcによるピクセル値の操作
- Gfcによる画像への描画
- Gfcによる画像の保存
- Gfcリファレンスマニュアル
例題
反転処理とは,ピクセルの各成分の値を, 最大値(8ビットなら255)からもとの値を引いた値に置き換えるものです. これにより,たとえば,白は黒になり,赤はシアンになります.
プログラムの仕様
プログラムの流れは,次の通りになるでしょう.
- 画像をファイルから読みこむ
- ピクセル値を反転する
- 画像に全体を4分割する白い枠を書き込む
- 結果として得られた画像をファイルに保存する.
プログラム
例題のプログラムをRubyで記述すると, 以下のようになります. なお,各行の左端の数字は説明のために付けた行の番号で, プログラムには,この行番号は含まれません.
[行番号つきプログラムを別のウィンドウで開く] [行番号なしのプログラム]
このプログラム(invert_image.rb)は次のように実行します. このプログラムでは, 入力する画像ファイルと出力する画像ファイルを指定する必要があります. 入力される画像ファイルは,フルカラー画像であることを仮定しています. グレイスケール画像ではうまく動作しません.
正しく処理が行われれば,別のウィンドウで画像が表示されます. 新たに起動されたのは,displayという別のプログラムです. 画像上で右ボタンを押すとメニューがでます. メニューからQuitを選ぶか, ^Q([Ctrl]+[q])でプログラムを終了できます.
この実行例では,出力ファイルとして「-」を指定しています. こう指定することで,invert_image.rbでは, 画像ファイルを標準出力へ書き出します. 標準出力は,パイプにより,リダイレクトされて, displayコマンドの標準入力に流し込まれています. displayコマンドは,引数として指定された画像を表示します. 引数に「-」が指定されると,標準入力から画像を読みこみます. つまり,パイプによって, invert_image.rbからdisplayへ画像データが送り込まれているわけです.
ところで,この例では,どちらのプログラムでも, 「-」を標準入出力を意味する特殊ファイル名として利用していますが, どんなコマンドでも「-」をそのような意味で利用できるわけではありません.
require --- ライブラリの読み込み
Ruby本体に組み込まれていないライブラリを利用するには, まずそのライブラリを読みこむ必要があります. require "ライブラリ名"で, ライブラリを読みこむことができます. requireは,ライブラリを利用する前に実行する必要があります. 通常,プログラムの先頭で行います. 例題のプログラムでも,まず最初にrequireを実行して, gfcライブラリを読みこんでいます.
1
2 require "gfc"
3
Gfcによる画像の読み込み
コマンドライン引数の処理をして, 入力画像ファイル名と出力画像ファイル名を決定したのち, 13行めで画像を読みこんでいます.
12 # 画像を読みこむ
13 g = Gfc.load(infile)
Gfc.loadというメソッドを, Gfc.load("画像ファイル名")のように起動することで, 指定された画像ファイルのピクセルデータと画像に対する処理機能をもったGfcオブジェクトが新たに生成されます. loadメソッドは, Gfcのクラスメソッドです.
なお,Gfc.newというクラスメソッドで,白一色の画像を作ることができます. 引数には,画像の幅と高さ, およびフルカラー画像にするか,グレイスケール画像にするかを指定します. 詳しくはGfcリファレンスマニュアルを参照して下さい.
Gfcによるピクセル値の操作
画像を読み込んだ後に,ピクセルの値を順に反転していきます. Gfcオブジェクトには,各ピクセルに対して, ブロックで指定された処理を施して,最後に評価した式の値に ピクセルデータを置き換えるイテレータ set_each!が用意されています.
15 # 全pixelの各成分を反転する
16 g.set_each! do |pixel|
17 pixel.r = 255 - pixel.r
18 pixel.g = 255 - pixel.g
19 pixel.b = 255 - pixel.b
20 pixel
21 end
ブロックに渡されるのは,ピクセルオブジェクトです. この例題の場合のブロックパラメタpixelには, Gfcオブジェクトgの画像のピクセルが順に渡されることになります. また,ブロックの内部に示されている通り, フルカラーピクセルオブジェクトの場合は,r,g,bというメソッドで RGBの各成分を参照できます. また同様にして,成分への値の代入もできます. r,g,bの代わりに,[0],[1],[2]というインデクスを使うこともできます. なお,グレイスケールピクセルの場合には, r,g,bではなく,iというメソッドを用います.
Gfcによる画像への描画
反転処理を行った後,画像を4分割する白い枠を描きます. そのためにまず画像のサイズを取得します. つづいて,描画色を白に設定してから, 画像の縁に長方形を描きます. また,画像の中央を通るように,水平な線分と垂直な線分を描いて, 画像を4分割します.
23 # 白い枠と白い十字を入れて,画像を4分割する
24 w,h = g.size # 画像のサイズを得る(幅,高さ)
25 g.set_foreground(0xffffff) # 描画色を白に設定する
26 g.draw_rect(0,0,w,h) # (0,0)を左上角とするw×hの長方形を描く
27 g.draw_hline(0,w-1,h/2) # (0,h/2)から(w-1,h/2)まで水平な線分を描く
28 g.draw_vline(0,h-1,w/2) # (0,w/2)から(h-1,w/2)まで垂直な線分を描く
Gfcオブジェクトの画像のサイズを得るには, sizeというメソッドを利用します. sizeは,幅と高さのデータを返します. 24行めでは,多重代入により,二つの変数「w,h」のそれぞれで,これらの値を受け取っています. つまりこの場合,wに画像の幅,hに画像の高さが代入されます.
25行めでは,画像に描画するときに使う色(デフォルトの描画色)を指定しています. ここで指定している色は白です. Gfcオブジェクトには,デフォルトの描画色が定められています. 描画を行うメソッドで個別に色を指定しない場合は,この描画色が利用されます. 描画メソッドで個別に色を指定した場合には,その色が優先されます. 色指定の詳細については,Gfcリファレンスマニュアルを見て下さい.
26〜28行めで,実際に,長方形,水平な線分,垂直な線分の描画を行っています. なお,Gfcには,これら以外の描画メソッド, たとえば,(水平・垂直以外の)一般の線分を描くメソッドや 三角形を描くメソッドなどは, 実習の都合上,用意されていません.
Gfcによる画像の保存
例題のプログラムでは,最後に,でき上がった画像データをファイルに保存しています.
30 # 画像を保存する
31 g.save(outfile)
画像を保存するには,saveというメソッドを用います. 引数として,保存先を指定します. ファイル名を指定すれば,そのファイルに保存します. 上の実行例で示したように, "-"を指定すると,標準出力へ画像が送り込まれます (直接$stdoutを指定することもできます). また,画像フォーマットを追加で指定することもできます. 指定しない場合には,PNG形式で保存します. フォーマットの指定方法については, リファレンスマニュアルを参照して下さい.