第 5 章 GdkPixbuf を使った画像アプリケーションの作成 65
5.1.1 画像の読み込み
GdkPixbufでは,関数gdk pixbuf new from fileを使うことで,画像ファイルから画像データを読み込むことができます.
GdkPixbufで扱える画像フォーマットを表5.1に示します.
G d k P i x b u f* g d k _ p i x b u f _ n e w _ f r o m _ f i l e (c o n s t c h a r * f i l e n a m e , G E r r o r * * e r r o r ) ;
GErrorは次のように定義されています.関数の引数に与える場合には,値をNULLに初期化してから与える必要があり
ます.
t y p e d e f s t r u c t { G Q u a r k d o m a i n ;
g i n t c o d e ;
g c h a r * m e s s a g e ; } G E r r o r;
ファイルの読み込み等でエラーが発生した場合は,関数の戻り値はNULLとなり,GError構造体の変数errorにはエラー情 報が格納されます.以下は読み込み許可のないファイルと存在しないファイルを引数に与えた場合のエラーコードとエラーメッ セージの例です.
$ ./read_image cannotread.png error->code : 2
error->message :
表5.1 GdkPixbufで扱うことができる画像フォーマット 画像フォーマット指定 読み込み 書き込み
jpeg ○ ○
png ○ ○
ico ○ ○
ani ○ ×
bmp ○ ×
gif ○ ×
pnm ○ ×
ras ○ ×
tga ○ ×
tiff ○ ×
xbm ○ ×
xpm ○ ×
ファイル ’cannotread.png’ のオープンに失敗しました: 許可がありません
$ ./read_image nothing.png error->code : 4
error->message :
ファイル ’nothing.png’ のオープンに失敗しました: そのようなファイルやディレクト
リはありません
GdkPixbuf構造体を生成するには,そのほかに次のような関数があります.
• gdk pixbuf new
画像サイズ等を指定してGdkPixbuf構造体を生成します.
G d k P i x b u f* g d k _ p i x b u f _ n e w (G d k C o l o r s p a c e c o l o r s p a c e , g b o o l e a n h a s _ a l p h a , i n t b i t s _ p e r _ s a m p l e ,
i n t w i d t h ,
i n t h e i g h t ) ;
GdkColorspaceにはGDK COLORSPACE RGBを与えます.また,has alphaは透過領域を持つ画像を作成する場合
はTRUEを,そうでない場合はFALSEを与えます.画像は一般に赤,緑,青の3つの色情報で表現されます.has alpha をTRUEとした場合には,3つの色情報に透過度を表す情報も加わります.メモリ上ではこれらの情報は,画像の点ご とに並んで格納されますが,イメージとしては,それぞれの情報を持つ平面が重なって画像を表現すると考えたほうがわ かりやすいかもしれません.この平面をチャネルもしくはプレーンと呼びます.また,画像の各点のチャネルごとの情報 量を表す値bits per sampleは現在では8(単位はビット)のみサポートしています.
• gdk pixbuf new from data
画像データからGdkPixbuf構造体を生成します.画像データはguchar型の1次元配列として与えます.
G d k P i x b u f*
g d k _ p i x b u f _ n e w _ f r o m _ d a t a (c o n s t g u c h a r * d a t a , G d k C o l o r s p a c e c o l o r s p a c e ,
g b o o l e a n h a s _ a l p h a ,
i n t b i t s _ p e r _ s a m p l e ,
i n t w i d t h ,
i n t h e i g h t ,
i n t r o w s t r i d e ,
G d k P i x b u f D e s t r o y N o t i f y d e s t r o y _ f n , g p o i n t e r d e s t r o y _ f n _ d a t a ) ;
GdkPixbufDestroyNotifyは次のように定義されており,画像データを解放する関数を与えます.destroy fn dataには
GdkPixbufDestroyNotify関数の第2引数に与えるユーザデータを指定します.
v o i d ( *G d k P i x b u f D e s t r o y N o t i f y) (g u c h a r * p i x e l s , g p o i n t e r d a t a ) ;
また,第7引数のrowstrideは,画像の1行分のバイト数を表します.つまり,幅W のカラー画像の場合,3W となり
ます(アルファチャネルがない場合).しかし,幅が4の倍数ではない画像を読み込んだ場合は異なる値となります.こ れは処理の効率化のために,1行分のデータ数が4バイトの倍数になるように,実際には使用しない余計な領域を追加し ていることが原因です.具体的には次のように計算できます.
rowstride= 3W+ (4−3W%4)
ここでa%bはaをbで割った余りを表します.
• gdk pixbuf new from xpm data
XPMデータからGdkPixbuf構造体を生成します.
G d k P i x b u f* g d k _ p i x b u f _ n e w _ f r o m _ x p m _ d a t a (c o n s t c h a r * * d a t a ) ;
• gdk pixbuf new from inline
インラインデータからGdkPixbuf構造体を生成します.
G d k P i x b u f* g d k _ p i x b u f _ n e w _ f r o m _ i n l i n e (g i n t d a t a _ l e n g t h , c o n s t g u i n t 8 * d a t a , g b o o l e a n c o p y _ p i x e l s , G E r r o r * * e r r o r ) ;
data lengthにはデータの長さを与えますが,−1を指定するとすべてのデータを使用します.また,copy pixelsに
TRUEを指定するとデータをローカルにコピーします.
インラインデータはgdk-pixbuf-csourceというコマンドラインツールを使って作成できます.
$ gdk-pixbuf-csource --name="icon_pixbuf" /usr/share/pixmap/gnome-terminal.png
> icon.h
インラインデータは次のような形式をしています.変数名はgdk-pixbuf-csourceコマンドの–nameオプションで指定でき ます.
1 / * G d k P i x b u f R G B A C - S o u r c e i m a g e d u m p 1 -by t e - run - l e n g t h - e n c o d e d * /
2
3 # i f d e f _ _ S U N P R O _ C
4 # p r a g m a a l i g n 4 ( i c o n _ p i x b u f )
5 # e n d i f
6 # i f d e f _ _ G N U C _ _
7 s t a t i c c o n s t g u i n t 8 i c o n _ p i x b u f [ ] _ _ a t t r i b u t e _ _ ( ( _ _ a l i g n e d _ _ ( 4 ) ) ) =
8 # e l s e
9 s t a t i c c o n s t g u i n t 8 i c o n _ p i x b u f [ ] =
10 # e n d i f
11 { " "
12 / * P i x b u f m a g i c ( 0 x 4 7 6 4 6 b 5 0 ) * /
13 " G d k P "
14 / * l e n g t h : h e a d e r ( 2 4 ) + p i x e l _ d a t a ( 7 1 0 4 ) * /
15 " \ 0 \ 0 \ 3 3 \ 3 3 0 "
16 / * p i x d a t a _ t y p e ( 0 x 2 0 1 0 0 0 2 ) * /
17 " \ 2 \ 1 \ 0 \ 2 "
18 / * r o w s t r i d e ( 1 9 2 ) * /
19 " \ 0 \ 0 \ 0 \ 3 0 0 "
20 / * w i d t h ( 4 8 ) * /
21 " \ 0 \ 0 \ 0 " " 0 "
22 / * h e i g h t ( 4 8 ) * /
23 " \ 0 \ 0 \ 0 " " 0 "
24 / * p i x e l _ d a t a : * /
25 " \ 3 7 7 \ 0 \ 0 \ 0 \ 0 \ 2 2 2 \ 0 \ 0 \ 0 \ 0 \ 6 \ 0 \ 0 \ 0 \ 1 \ 0 \ 0 \ 0 \ 2 \ 0 \ 0 \ 0 \ 4 \ 0 \ 0 \ 0 \ 7 \ 0 . . . "
26 " \ 0 \ 0 \ 1 2 \ 2 0 4 \ 0 \ 0 \ 0 \ 1 3 \ 2 3 3 \ 0 \ 0 \ 0 \ 1 4 \ 2 0 3 \ 0 \ 0 \ 0 \ 1 3 \ 6 \ 0 \ 0 \ 0 \ 1 2 \ 0 \ . . . "
27 " \ 0 \ 0 \ 7 \ 0 \ 0 \ 0 \ 4 \ 0 \ 0 \ 0 \ 2 \ 0 \ 0 \ 0 \ 1 \ 2 0 2 \ 0 \ 0 \ 0 \ 0 \ 4 \ 0 \ 0 \ 0 \ 2 \ 0 \ 0 \ 0 " " . . . "
28 " \ 1 \ 1 \ 1 \ 3 7 7 \ 2 4 6 \ 0 \ 0 \ 0 \ 3 7 7 \ 2 0 \ 0 \ 0 \ 0 K \ 0 \ 0 \ 0 \ 1 4 \ 0 \ 0 \ 0 \ 7 \ 0 \ 0 \ 0 \ 2 \ . . . "
29 " \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 4 \ 0 \ 0 \ 0 \ 3 7 7 \ 3 4 0 \ 3 3 6 \ 3 3 4 \ 3 3 2 \ 3 5 2 \ 3 5 1 \ 3 4 6 \ 3 7 7 \ 3 5 7 . . . "
30 " \ 3 7 7 \ 3 6 0 \ 3 5 7 \ 3 5 5 \ 3 7 7 \ 3 6 1 \ 3 6 0 \ 3 5 6 \ 3 7 7 \ 3 6 2 \ 3 6 1 \ 3 5 7 \ 3 7 7 \ 3 6 0 \ 3 6 0 . . . "
31 . . .