• 検索結果がありません。

画像の表示

ドキュメント内 ÆþÌçGTK+ (ページ 81-85)

第 5 章 GdkPixbuf を使った画像アプリケーションの作成 65

5.3 画像の表示

これまで紹介した関数を使用すれば,画像データを簡単にメモリ上に読み込んで扱うことができます.では,画像データをメ モリ上で扱うだけではなく,ウィンドウ上に表示するにはどうすればいいでしょうか.この節では,画像をウィンドウ上に表示 する方法をいくつか紹介します.

5.3.1 GtkImage ウィジェットによる画像の表示

チュートリアルの2.4節(p.15)でも紹介したように,画像を表示する一番簡単な方法はイメージウィジェット(GtkImage) を使用する方法です.GtkImageウィジェットは名前の通り画像を扱うウィジェットです.GtkImageウィジェットを使用した 画像の表示の例を,ソース5–1に示します.

ソース5–1 GtkImageウィジェットによる画像の表示: display1.c

1 # i n c l u d e <g t k / g t k . h >

2 # i n c l u d e <s t d l i b . h >

3 4 i n t

5 m a i n (i n t a r g c , c h a r * a r g v [ ] )

6 {

7 G t k W i d g e t * w i n d o w ;

8 G t k W i d g e t * i m a g e ;

9

10 i f ( a r g c < 2 )

11 {

12 g _ p r i n t ( " U s a g e : . / d i s p l a y 1 i m a g e f i l e \ n " ) ;

13 e x i t ( 0 ) ;

14 }

15 g t k _ i n i t ( & a r g c , & a r g v ) ;

16

17 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 ) ;

18 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 1 " ) ;

19 g _ s i g n a l _ c o n n e c t ( G _ O B J E C T ( w i n d o w ) , " d e s t r o y " ,

20 G _ C A L L B A C K ( g t k _ m a i n _ q u i t ) , N U L L ) ;

21 i m a g e = g t k _ i m a g e _ n e w _ f r o m _ f i l e ( a r g v [ 1 ] ) ;

22 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 ) , i m a g e ) ;

23

24 g t k _ w i d g e t _ s h o w _ a l l ( w i n d o w ) ;

25 g t k _ m a i n ( ) ;

26

27 r e t u r n 0 ;

28 }

ソース 5–1を見てもわかるように,GtkImagウィジェットをGtkWindowウィジェットにパックするだけで,画像を表示 できます.この例ではGdkPixbufを使用せずに,関数gtk image new from file を使用することで,画像ファイルから直接

GtkImageウィジェットを作成できます.

G t k W i d g e t* g t k _ i m a g e _ n e w _ f r o m _ f i l e (c o n s t g c h a r * f i l e n a m e ) ;

次の関数を使用することで,GdkPixbufやGdkPixmapからGtkImageウィジェットを作成することも可能です.

図5.1 GdkImageウィジェットによる画像の表示

G t k W i d g e t* g t k _ i m a g e _ n e w _ f r o m _ p i x b u f (G d k P i x b u f * p i x b u f ) ; G t k W i d g e t* g t k _ i m a g e _ n e w _ f r o m _ p i x m a p (G d k P i x m a p * p i x m a p ,

G d k B i t m a p * m a s k ) ;

逆に次の関数を使用することで,GtkImageウィジェットからGdkPixbufやGdkPixmap形式のデータを取得することもで きます.

G d k P i x b u f* g t k _ i m a g e _ g e t _ p i x b u f (G t k I m a g e * i m a g e ) ; v o i d g t k _ i m a g e _ g e t _ p i x m a p (G t k I m a g e * i m a g e ,

G d k P i x m a p * * p i x m a p , G d k B i t m a p * * m a s k ) ;

5.3.2 GtkDrawingArea ウィジェットによる画像の表示

画像の表示には,GtkDrawingAreaウィジェットを利用することもできます.このウィジェットは図形や画像を描画するウィ ジェットで,GDKライブラリで定義されたGdkDrawable(これ以降はドローアブルと呼ぶことにします)という描画領域を 持ちます.なお,ウィンドウウィジェットもドローアブルを持つため,ウィンドウ上に直接描画することも可能です.

GtkDrawingAreaウィジェットはGtkImageウィジェットに比べて扱いが多少面倒ですが,表示した画像の上にさらに図

形を描画するといったことが可能になります.GtkDrawingAreaウィジェットを使った画像描画のソースコードをソース5–2

(p.72)に示します.

画像の読み込み(45行目)

ウィンドウに表示する画像を,関数gdk pixbuf new from fileを使ってファイルから読み込みます.

GtkDrawingAreaウィジェットの設定(52–55行目)

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 ) ; コールバック関数の設定(56–57行目)

GtkDrawingAreaウィジェットで画像を描画する場合には,expose-eventシグナルのコールバック関数に画像描画のコー

ドを記述するか,画像を描画する関数を呼び出す記述をします.ユーザがドローアブル上に図形を描画する場合,図形を描画し ているウィンドウが他のウィンドウで隠れると,図形を再描画しない限り,隠された領域が自動的に描画されることはありませ ん.このような再描画が必要になったときに発生するシグナルが,expose-eventシグナルです.そのため,一般的にはこのシグ ナルに対するコールバック関数で描画処理を行います.

画像の描画(16–23行目)

ここでは画像を描画するために,GdkPixbuf型のデータからGdkPixmap型のデータ(ピックスマップ)を作成し,作成し たピックスマップをドローアブルに描画しています.

GdkPixbuf型のデータからピックスマップを生成するには,関数gdk pixbuf render pixmap and maskを使います.

v o i d 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 (G d k P i x b u f * p i x b u f ,

G d k P i x m a p * * p i x m a p _ r e t u r n , G d k B i t m a p * * m a s k _ r e t u r n , i n t a l p h a _ t h r e s h o l d ) ;

第1引数 GdkPixbuf型の画像データ.

第2引数 生成されるピックスマップ.

第3引数 生成されるビットマップ(マスクデータ).

第4引数 画像データがアルファチャネルを持つ場合の透明度のしきい値.0から255の範 囲で指定する.

画像データにアルファチャネルがある場合には,第3引数に与えた変数に,第4引数に与えたしきい値でアルファチャネルを 2値化したマスク情報が返ります.

この方法を使っていったん画像データを背景に登録すると,画像の再描画は関数gdk window clearを呼び出すのみで済むと いう利点があります.

gdk pixbuf composite color

ソース5–2では,関数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は表5.3のように定義されています.

表5.3 画像補間の種類

値 説明

GDK INTERP NEAREST 最近傍補間.

GDK INTERP TILES 各点を平行四辺形として扱い,各点間の輪郭をアンチエイリアシングする.

GDK INTERP BILINEAR 線形補間.

GDK INTERP HYPER 2次補間.

最後に,関数gdk window set back pixmapで生成したピックスマップをドローアブル(ここではGtkDrawingAreaウィ

ジェットのメンバwindowがドローアブルになる)にセットし,関数gdk window clearで描画領域の更新処理を行っています.

v o i d g d k _ w i n d o w _ s e t _ b a c k _ p i x m a p (G d k W i n d o w * w i n d o w , G d k P i x m a p * p i x m a p ,

g b o o l e a n p a r e n t _ r e l a t i v e ) ; v o i d g d k _ w i n d o w _ c l e a r (G d k W i n d o w * w i n d o w ) ;

ソース5–2 GtkDrawingAreaウィジェットによる画像の表示: display2.c

1 # i n c l u d e <g t k / g t k . h >

2 # i n c l u d e <s t d l i b . h >

3

4 s t a t i c g i n t

5 c b _ e x p o s e (G t k W i d g e t * w i d g e t ,

6 G d k E v e n t E x p o s e * e v e n t ,

7 g p o i n t e r u s e r _ d a t a )

8 {

9 G d k P i x b u f * p i x b u f = (G d k P i x b u f * ) u s e r _ d a t a ;

10 G d k P i x b u f * b a c k g r o u n d ;

11 G d k P i x m a p * p i x m a p ;

12 i n t w , h ;

13

14 w = g d k _ p i x b u f _ g e t _ w i d t h ( p i x b u f ) ;

15 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 ) ;

16 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 ) ;

17 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 ,

18 0 , 0 , w , h , 0 , 0 , 1 . 0 , 1 . 0 ,

19 G D K _ I N T E R P _ B I L I N E A R , 2 5 5 , 0 , 0 , 16 ,

20 0 x a a a a a a , 0 x 5 5 5 5 5 5 ) ;

21 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 ) ;

22 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 ) ;

23 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 ) ;

24

25 g _ o b j e c t _ u n r e f ( b a c k g r o u n d ) ;

26 g _ o b j e c t _ u n r e f ( p i x m a p ) ;

27

28 r e t u r n T R U E ;

29 }

30 31 i n t

32 m a i n (i n t ar g c , c h a r * a r g v [ ] )

33 {

34 G t k W i d g e t * w i n d o w ;

35 G t k W i d g e t * c a n v a s ;

36 G d k P i x b u f * p i x b u f ;

37

38 i f ( a r g c < 2 )

39 {

40 g _ p r i n t ( " U s a g e : . / d i s p l a y 2 i m a g e f i l e \ n " ) ;

41 e x i t ( 0 ) ;

42 }

43 g t k _ i n i t ( & a r g c , & a r g v ) ;

図5.2 GtkDrawingAreaウィジェットによる画像の表示

44

45 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 ) ;

46

47 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 ) ;

48 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 " ) ;

49 g _ s i g n a l _ c o n n e c t ( G _ O B J E C T ( w i n d o w ) , " d e s t r o y " ,

50 G _ C A L L B A C K ( g t k _ m a i n _ q u i t ) , N U L L ) ;

51

52 c a n v a s = g t k _ d r a w i n g _ a r e a _ n e w ( ) ;

53 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 ,

54 g d k _ p i x b u f _ g e t _ w i d t h ( p i x b u f ) ,

55 g d k _ p i x b u f _ g e t _ h e i g h t ( p i x b u f ) ) ;

56 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 " ,

57 G _ C A L L B A C K ( c b _ e x p o s e ) , p i x b u f ) ;

58 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 ) ;

59

60 g t k _ w i d g e t _ s h o w _ a l l ( w i n d o w ) ;

61 g t k _ m a i n ( ) ;

62

63 r e t u r n 0 ;

64 }

ドキュメント内 ÆþÌçGTK+ (ページ 81-85)