ソフトウェア設計及び演習2017

GDK2017::GdkPixbuf

GdkPixbuf とは

GTK, GDK を用いてプログラムを開発する際に、 画像データを簡単に扱えるようにする目的で作られたライブラリ

GdkPixbuf の特徴

GdkPixbuf では、pixmap ではなく pixbuf と呼ばれる画像領域が使われる.

GdkPixbuf の主な特徴

  • 多様なフォーマットの画像ファイルデータを読み込み、書き込み、表示ができる
  • 読み込んだ画像データの加工(拡大縮小など)の関数も用意されている
  • 画像データを二次元配列データとして処理するのが容易である.(読み込み画像に関係なくデータ形式が(RGB24bit+アルファ)に統一されるため.)

画像データ用に確保されたメモリ領域という意味では pixmap も pixbuf も同じだが、pixbuf には直接線を引いたり文字を書いたり等ができるわけではない

GdkPixbuf を用いたプログラミング

(0)ヘッダファイル

#include <gdk-pixbuf/gdk-pixbuf.h>

(1)画像ファイルの pixbuf への読み込み

GdkPixbuf* gdk_pixbuf_new_from_file (const char *filename, 
                                     GError **error);
GdkPixbuf* gdk_pixbuf_new_from_file_at_size (const char *filename, 
                                             int width, 
                                             int height, 
                                             GError **error);
GdkPixbuf* gdk_pixbuf_new_from_file_at_scale (const char *filename,
                                              int width,
                                              int height,
                                              gboolean preserve_aspect_ratio,
                                              GError **error);

以下の関数で読み込むと、画像データ自体がコンパイル後の実行ファイル内に格納されるので、 実行時に別途画像ファイルを用意する必要がなくなるが、 実行ファイルはその分大きくなる

GdkPixbuf* gdk_pixbuf_new_from_xpm_data (const char **data);
GdkPixbuf* gdk_pixbuf_new_from_inline (gint data_length,
                                       const guint8 *data,
                                       gboolean copy_pixels,
                                       GError **error);
使い方
GdkPixbuf *pixbuf;

pixbuf = gdk_pixbuf_new_from_file( "foo.jpg", NULL );
  • filename に画像ファイル名を指定することで、必要な pixbuf 領域を生成し画像データを読み込む
ここの環境で読み込める画像形式
名前 説明 書き込み スケーラブル 認識する拡張子
ani The ANI image format     ani
bmp The BMP image format   bmp
gif The GIF image format     gif
icns The ICNS image format     icns
ico The ICO image format   ico,cur
jpeg2000 The JPEG 2000 image format     jp2,jpc,jpx,j2k,jpf
jpeg The JPEG image format   jpeg,jpe,jpg
pcx The PCX image format     pcx
png The PNG image format   png
pnm The PNM/PBM/PGM/PPM image format family     pnm,pbm,pgm,ppm
qtif The QTIF image format     qtif,qif
ras The Sun raster image format     ras
svg Scalable Vector Graphics   svg,svgz,svg.gz
tga The Targa image format     tga,targa
tiff The TIFF image format   tiff,tif
wbmp The WBMP image format     wbmp
xbm The XBM image format     xbm
xpm The XPM image format     xpm
wmf Windows Metafile     wmf,apm
GdkPixdata The GdkPixdata format     gdkp

(2)読み込んだ画像の各種情報の取得

GdkColorspace gdk_pixbuf_get_colorspace       (const GdkPixbuf *pixbuf);
int           gdk_pixbuf_get_n_channels       (const GdkPixbuf *pixbuf);
gboolean      gdk_pixbuf_get_has_alpha        (const GdkPixbuf *pixbuf);
int           gdk_pixbuf_get_bits_per_sample  (const GdkPixbuf *pixbuf);
guchar*       gdk_pixbuf_get_pixels           (const GdkPixbuf *pixbuf);
int           gdk_pixbuf_get_width            (const GdkPixbuf *pixbuf);
int           gdk_pixbuf_get_height           (const GdkPixbuf *pixbuf);
int           gdk_pixbuf_get_rowstride        (const GdkPixbuf *pixbuf);
const gchar*  gdk_pixbuf_get_option           (GdkPixbuf *pixbuf, 
                                               const gchar *key);
  • 画像サイズを得る関数 gdk_pixbuf_get_width, gdk_pixbuf_get_height はよく使う
GdkPixbufの構造

圧縮されていない画像データが "行列" のような形式で格納

  • 行方向には画像の上から下まで順にピクセル・データが格納
  • 各行は画像の左から右に向かってデータが格納
  • 各ピクセル・データの終端は画像以外の何らかのデータが埋められている場合あり

下の図と計算式は「8ビット/チャンネル」の場合。たいていのデータはこの形式

p = pixels + y * rowstride + x * channels

   pixels = gdk_pixbuf_get_pixels(pixbuf);
rowstride = gdk_pixbuf_get_rowstride(pixbuf);
 channels = gdk_pixbuf_get_n_channels(pixbuf);

(3)pixbuf の描画

GtkWidget* gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf);
  • gtk_image_new_from_pixbuf
    • 入門GTK+ 3版pdf:70(82)ページ
  • pixbuf から image を作って、コンテナ(ボタン、ウィンドウなど)にのせる
GtkWidget* gtk_image_new_from_file (const gchar *filename);
  • gtk_image_new_from_file
    • 入門GTK+ 3版pdf:69(81)ページ
  • 特に加工するつもりがないのなら、ファイルを指定して image を作れば、GTK が勝手に gdk-pixbuf ライブラリを利用してファイルを読み込んでくれる

(4)画像の拡大・縮小、回転

GdkPixbuf* gdk_pixbuf_scale_simple (const GdkPixbuf *src,
                                    int dest_width,
                                    int dest_height,
                                    GdkInterpType interp_type);
void gdk_pixbuf_scale (const GdkPixbuf *src,
                       GdkPixbuf *dest,
                       int dest_x, int dest_y,
                       int dest_width, int dest_height,
                       double offset_x, double offset_y,
                       double scale_x, double scale_y,
                       GdkInterpType interp_type);

いずれも pixbuf の画像データの拡大・縮小をする関数。 上の関数では拡大・縮小後の画像の pixbuf を新たに生成してくれるが、 下の関数の場合には拡大・縮小された画像用の pixbuf を予め生成しておく必要がある

GdkPixbuf* gdk_pixbuf_rotate_simple (const GdkPixbuf *src,
                                     GdkPixbufRotation angle);

その他の関数

以上のほかによく使われると思われる関数

空の pixbuf 領域を生成する
GdkPixbuf* gdk_pixbuf_new (GdkColorspace colorspace,
                           gboolean has_alpha,
                           int bits_per_sample,
                           int width, int height);
pixbuf に透過情報を追加する
GdkPixbuf* gdk_pixbuf_add_alpha (const GdkPixbuf *pixbuf,
                                 gboolean substitute_color,
                                 guchar r, guchar g, guchar b);
pixbuf の一部を他の pixbuf へコピーする
void gdk_pixbuf_copy_area (const GdkPixbuf *src_pixbuf,
                           int src_x, int src_y,
                           int width, int height,
                           GdkPixbuf *dest_pixbuf,
                           int dest_x, int dest_y);
ドローワブル領域(pixmap等)を pixbuf に変換する
GdkPixbuf* gdk_pixbuf_get_from_drawable (GdkPixbuf *dest,
                                         GdkDrawable *src,
                                         GdkColormap *cmap,
                                         int src_x, int src_y,
                                         int dest_x, int dest_y,
                                         int width, int height);

この他にも画像ファイルへの保存等いろいろな関数があるが、 その他についてはGDK-PixBuf Reference Manualを参照

また、GdkPixbuf の関数ではないが、使われなくなった pixbuf については以下の関数で領域を解放する必要がある

void g_object_unref (gpointer object);

サンプル

ソースプログラムの所在
ファイルリスト
  • gtk_lib.h gtk_lib.c
    • gtkを(ほんの少しだけ)簡単に利用できるようにまとめたラッパー(ライブラリ)
    • 以前の講義担当だった鈴木先生が作られたものを少し変更
  • gdk_pixbuf_lib.h gdk_pixbuf_lib.c
    • gdk_pixbufの機能を紹介するためのサンプルライブラリ
    • 以前に中谷先生が作られたものを少し変更
  • gdk_pixbuf.c
    • メインプログラム.アニメーションgifの表示,画像の拡大縮小,画像の回転,透過率の変更などのサンプル
実行手順
 #svnから持ってくる(実行した直下にgdk_pixbufディレクトリができる)
 svn export https://svn.cis.iwate-u.ac.jp/svn/csd/kimura/gdk_pixbuf/
 
 #持ってきたディレクトリに移動
 cd gdk_pixbuf
 
 #make
 make
 
 #実行
 ./gdk_pixbuf

CairoでGdkPixbufのサンプル

  • Cairoを使って,画像を拡大・縮小,回転,半透明化するサンプル
ソースプログラムの所在
ファイルリスト
  • gtk_lib.h gtk_lib.c
    • gtkを(ほんの少しだけ)簡単に利用できるようにまとめたラッパー(ライブラリ)
    • 以前の講義担当だった鈴木先生が作られたものを少し変更
  • cairo_pixbuf_lib.h cairo_pixbuf_lib.c
    • cairo_pixbufの機能を紹介するためのサンプルライブラリ
    • 以前に中谷先生が作られたものを少し変更
  • cairo_pixbuf.c
    • メインプログラム.アニメーションgifの表示,画像の拡大縮小,画像の回転,透過率の変更などのサンプル
実行手順
 #svnから持ってくる(実行した直下にcairo_pixbufディレクトリができる)
 svn export https://svn.cis.iwate-u.ac.jp/svn/csd/kimura/cairo_pixbuf/
 
 #持ってきたディレクトリに移動
 cd cairo_pixbuf
 
 #make
 make
 
 #実行
 ./cairo_pixbuf

リンク


最終更新日:2017/04/28 15:05:55