第 5 章 GdkPixbuf 61
5.3 画像の表示
5.3.2 GtkDrawingArea ウィジェットによる画像の表示
画像の表示には,図形の表示で扱ったGtkDrawingAreaウィジェットを利用することもできます. GtkImage ウィジェットに比べて扱いが面倒ですが,表示した画像の上にさらに図形を描画するといったことが可能にな
ります. GtkDrawingAreaウィジェットを使った画像描画のソースコードをソース5–2に示します.
画像の読み込み(18行目)
ウィンドウに表示するための画像を関数gdk pixbuf new from fileを使ってファイルから読み込みます.
GtkDrawingAreaウィジェットの設定 (25–28行目)
GtkImageウィジェットは,画像の大きさに応じて自動的に最適な大きさに伸縮しますが, GtkDrawingArea
ウィジェットを用いて画像を表示する場合には, ユーザが最適な大きさを指定する必要があります. 関数 gtk widget set size requestはウィジェットの大きさを設定する関数です.
v o i d g t k _ w i d g e t _ s e t _ s i z e _ r e q u e s t (G t k W i d g e t * w i d g e t ,
g i n t w i d t h , g i n t h e i g h t ) ;
コールバック関数の設定(29–30行目)
GtkDrawingAreaウィジェットで画像を描画する場合には, ”expose event”シグナルのコールバック関数
に画像描画のコードを記述するか,画像を描画する関数を呼び出す記述をします.
画像の描画(6–7行目)
関数gdk draw pixbufを使って,画像データを描画します. 第1引数drawableには画像データを描画する ドローアブルを指定します. ソース 5–2では, GtkDrawingAreaのwindowメンバをドローアブルとして指定 しています. 第2引数のgcは特に指定せずに, NULLを与えておいても構いません.
第3, 4引数はドローアブルのどの座標から描画を開始するかを指定します. そして,第5引数から第8引数 で,描画する画像の範囲(開始座標と幅,高さ)を指定します. width, heightに−1を指定すると, 自動的に画 像全体の幅と高さとなります.
v o i d g d k _ d r a w _ p i x b u f (G d k D r a w a b l e * d r a w a b l e ,
G d k G C * gc ,
G d k P i x b u f * p i x b u f ,
g i n t s r c _ x ,
g i n t s r c _ y ,
g i n t d e s t _ x ,
g i n t d e s t _ y ,
g i n t w i d t h ,
g i n t h e i g h t ,
G d k R g b D i t h e r d i t h e r ,
g i n t x _ d i t h e r ,
g i n t y _ d i t h e r ) ;
GdkRgbDitherは次のように定義されています. t y p e d e f e n u m
{
G D K _ R G B _ D I T H E R _ N O N E , G D K _ R G B _ D I T H E R _ N O R M A L , G D K _ R G B _ D I T H E R _ M A X } G d k R g b D i t h e r;
ソース 5–2 GtkDrawingAreaウィジェットによる画像の表示1 : display2.c
1 # i n c l u d e <g t k / g t k . h >
2
3 s t a t i c g i n t c b _ e x p o s e (G t k W i d g e t * w i d g e t ,
4 G d k E v e n t E x p o s e * e v e n t ,
5 g p o i n t e r d a t a ) {
6 g d k _ d r a w _ p i x b u f ( w i d g e t - >w i n d o w , N U L L , (G d k P i x b u f * ) d a t a ,
7 0 , 0 , 0 , 0 , -1 , -1 , G D K _ R G B _ D I T H E R _ N O N E , 0 , 0 ) ;
8 r e t u r n T R U E ;
9 }
10
11 i n t m a i n (i n t ar g c , c h a r * a r g v [ ] ) {
12 G t k W i d g e t * w i n d o w ;
13 G t k W i d g e t * c a n v a s ;
14 G d k P i x b u f * p i x b u f ;
図5.2 GtkDrawingAreaウィジェットによる画像の表示(その1)
15
16 g t k _ i n i t ( & a r g c , & a r g v ) ;
17
18 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 ( a r g v [ 1 ] , N U L L ) ;
19
20 w i n d o w = g t k _ w i n d o w _ n e w ( G T K _ W I N D O W _ T O P L E V E L ) ;
21 g t k _ w i n d o w _ s e t _ t i t l e ( G T K _ W I N D O W ( w i n d o w ) , " D i s p l a y à I m a g e à 2 " ) ;
22
23 c a n v a s = g t k _ d r a w i n g _ a r e a _ n e w ( ) ;
24 g t k _ w i d g e t _ s e t _ s i z e _ r e q u e s t ( c a n v a s ,
25 g d k _ p i x b u f _ g e t _ w i d t h ( p i x b u f ) ,
26 g d k _ p i x b u f _ g e t _ h e i g h t ( p i x b u f ) ) ;
27 g _ s i g n a l _ c o n n e c t ( G _ O B J E C T ( c a n v a s ) , " e x p o s e _ e v e n t " ,
28 G _ C A L L B A C K ( c b _ e x p o s e ) , p i x b u f ) ;
29 g t k _ c o n t a i n e r _ a d d ( G T K _ C O N T A I N E R ( w i n d o w ) , c a n v a s ) ;
30
31 g t k _ w i d g e t _ s h o w _ a l l ( w i n d o w ) ;
32 g t k _ m a i n ( ) ;
33
34 r e t u r n 0 ;
35 }
GtkDrawingAreaウィジェットを使う方法として, GdkPixbufデータからピックスマップ(GdkPixmap)
とビットマップ(GdkBitmap)を作成して,関数gdk window set back pixmapで画像データをGdkWindow の背景として設定する方法があります. この方法を使って一旦画像データを背景に登録すると画像の再描画は 関数gdk window clearを呼び出すのみで済むという利点があります. GdkPixbufデータからピックスマップ とビットマップを生成するには, 関数gdk pixbuf render pixmap and maskを使います.
ソース5–3では, 関数gdk pixbuf composite colorを使って透明部分にタイル柄を描画して,透明部分を演 出しています. この関数の最後の3つの引数(第15–17引数)で,タイルの大きさ, 1つ目のタイルの色, 2つ目 のタイルの色を指定しています.
v o i d g d k _ p i x b u f _ c o m p o s i t e _ c o l o r (c o n s t G d k P i x b u f * src , G d k P i x b u f * d e s t ,
i n t d e s t _ x ,
i n t d e s t _ y ,
i n t d e s t _ w i d t h ,
i n t d e s t _ h e i g h t ,
d o u b l e o f f s e t _ x ,
d o u b l e o f f s e t _ y ,
d o u b l e s c a l e _ x ,
d o u b l e s c a l e _ y ,
G d k I n t e r p T y p e i n t e r p _ t y p e ,
i n t o v e r a l l _ a l p h a ,
i n t c h e c k _ x ,
i n t c h e c k _ y ,
i n t c h e c k _ s i z e ,
g u i n t 3 2 c o l o r 1 ,
g u i n t 3 2 c o l o r 2 ) ;
第1引数: 入力画像 第2引数: 出力画像
第3引数: 入力画像の描画を開始するX座標 第4引数: 入力画像の描画を開始するY座標 第5引数: 描画する幅
第6引数: 描画する高さ
第7引数: 入力画像のオフセットのX座標 第8引数: 入力画像のオフセットのY座標 第9引数: 入力画像のX方向の拡大率 第10引数: 入力画像のY方向の拡大率 第11引数: 画素値の内挿方法
第12引数: 透明度の設定(0–255)
第13引数: チェッカーボードのオフセットのX座標 第14引数: チェッカーボードのオフセットのY座標
第15引数: チェッカーボードの大きさ(2の巾乗でなければならない) 第16引数: チェッカーボードの色1
第17引数: チェッカーボードの色2
入力画像をscale x, scale yだけ拡大して, (offset x, offset y)だけ平行移動した画像を出力画像の(dest x, dest y)から幅dest width,高さdest heightの矩形領域に描画する関数です. 透明領域は指定したチェッカー ボードで塗りつぶされます.
GdkInterpTypeは次のように定義されています. t y p e d e f e n u m {
G D K _ I N T E R P _ N E A R E S T , G D K _ I N T E R P _ T I L E S , G D K _ I N T E R P _ B I L I N E A R , G D K _ I N T E R P _ H Y P E R } G d k I n t e r p T y p e;
図5.3 GtkDrawingAreaウィジェットによる画像の表示(その2)
ソース 5–3 GtkDrawingAreaウィジェットによる画像の表示2 : display3.c
1 # i n c l u d e <g t k / g t k . h >
2
3 s t a t i c g i n t c b _ e x p o s e (G t k W i d g e t * w i d g e t ,
4 G d k E v e n t E x p o s e * e v e n t ,
5 g p o i n t e r d a t a ) {
6 G d k P i x b u f * p i x b u f = (G d k P i x b u f * ) d a t a ;
7 G d k P i x b u f * b a c k g r o u n d ;
8 G d k P i x m a p * p i x m a p ;
9 i n t w , h ;
10
11 w = g d k _ p i x b u f _ g e t _ w i d t h ( p i x b u f ) ;
12 h = g d k _ p i x b u f _ g e t _ h e i g h t ( p i x b u f ) ;
13 b a c k g r o u n d = 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 _ R G B , F A L S E , 8 , w , h ) ;
14 g d k _ p i x b u f _ c o m p o s i t e _ c o l o r ( p i x b u f , b a c k g r o u n d ,
15 0 , 0 , w , h , 0 , 0 , 1 . 0 , 1 . 0 ,
16 G D K _ I N T E R P _ B I L I N E A R , 2 5 5 , 0 , 0 , 16 ,
17 0 x a a a a a a , 0 x 5 5 5 5 5 5 ) ;
18 g d k _ p i x b u f _ r e n d e r _ p i x m a p _ a n d _ m a s k ( b a c k g r o u n d , & p i x m a p , N U L L , 2 5 5 ) ;
19 g d k _ w i n d o w _ s e t _ b a c k _ p i x m a p ( w i d g e t - >w i n d o w , p i x m a p , F A L S E ) ;
20 g d k _ w i n d o w _ c l e a r ( w i d g e t - >w i n d o w ) ;
21
22 g _ o b j e c t _ u n r e f ( b a c k g r o u n d ) ;
23 g _ o b j e c t _ u n r e f ( p i x m a p ) ;
24
25 r e t u r n T R U E ;
26 }
27
28 i n t m a i n (i n t ar g c , c h a r * a r g v [ ] ) {
29 G t k W i d g e t * w i n d o w ;
30 G t k W i d g e t * c a n v a s ;
31 G d k P i x b u f * p i x b u f ;
32
33 g t k _ i n i t ( & a r g c , & a r g v ) ;
34
35 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 ( a r g v [ 1 ] , N U L L ) ;
36
37 w i n d o w = g t k _ w i n d o w _ n e w ( G T K _ W I N D O W _ T O P L E V E L ) ;
38 g t k _ w i n d o w _ s e t _ t i t l e ( G T K _ W I N D O W ( w i n d o w ) , " D i s p l a y à I m a g e à 3 " ) ;
39
40 c a n v a s = g t k _ d r a w i n g _ a r e a _ n e w ( ) ;
41 g t k _ w i d g e t _ s e t _ s i z e _ r e q u e s t ( c a n v a s ,
42 g d k _ p i x b u f _ g e t _ w i d t h ( p i x b u f ) ,
43 g d k _ p i x b u f _ g e t _ h e i g h t ( p i x b u f ) ) ;
44 g _ s i g n a l _ c o n n e c t ( G _ O B J E C T ( c a n v a s ) , " e x p o s e _ e v e n t " ,
45 G _ C A L L B A C K ( c b _ e x p o s e ) , p i x b u f ) ;
46 g t k _ c o n t a i n e r _ a d d ( G T K _ C O N T A I N E R ( w i n d o w ) , c a n v a s ) ;
47
48 g t k _ w i d g e t _ s h o w _ a l l ( w i n d o w ) ;
49 g t k _ m a i n ( ) ;
50
51 r e t u r n 0 ;
52 }