画像データへの直接アクセス

概要

Gdk::Pixbuf::get_pixels()関数を使ってピクセルデータに直接アクセスする。

この関数はguint8型のポインタを返し、Gdk::Pixbuf::get_n_channels()の 戻り値が4の時はR,G,B,アルファ値の順にデータが格納されている。 また1行分のサイズはGdk::Pixbuf::get_rowstride()によって 取得できる。従って

guint8* data = m_pixbuf->get_pixels();
int channels = m_pixbuf->get_n_channels();
int stride = m_pixbuf->get_rowstride();
とすると(x,y)座標のG成分には data[ y * stride + x * channels + 1 ] によって アクセスできる。

次の例は読み込んだ画像の画素値を反転させるものである。

ソース

pixbuf2.cpp

#include <gtkmm.h>

class MainWin : public Gtk::Window
{
    Gtk::Image m_img;
    Glib::RefPtr< Gdk::Pixbuf > m_pixbuf;

public:
    MainWin();
};


MainWin::MainWin()
{
    m_pixbuf = Gdk::Pixbuf::create_from_file( "./test.png" );

    guint8* data = m_pixbuf->get_pixels();
    int channels = m_pixbuf->get_n_channels();
    int width = m_pixbuf->get_width();
    int height = m_pixbuf->get_height();
    int stride = m_pixbuf->get_rowstride();

    // 反転画像
    for( int row = 0; row < height ; ++row ){
        for( int col = 0; col < width ; ++col ){        

            int offset = row * stride + col * channels;
            data[ offset ] = -1 - data[ offset ];       // R
            data[ offset+1 ] = -1 - data[ offset+1 ];   // G
            data[ offset+2 ] = -1 - data[ offset+2 ];   // B
        }
    }

    m_img.set( m_pixbuf );

    add( m_img );
    show_all_children();
}


int main( int argc, char *argv[] )
{
    Gtk::Main kit( argc, argv );
    MainWin mainwin;
    Gtk::Main::run( mainwin );

    return 0;
}

コンパイル

必要なコンパイルオプションは pkg-config を使って取得する。

g++ pixbuf2.cpp -o pixbuf2 `pkg-config gtkmm-2.4 --cflags --libs`

結果