Gnome Canvas的學習筆記(1)

最近要在Linux手持設備上優化一個圖形的程序,被迫去學習Gnome Canvas。


1、有了GTK,爲什麼還要GnomeCanvas?


GnomeCanvas 是一個強大的、高級API的、高圖形渲染性能的圖形渲染引擎,提供豐富的圖像功能。GnomeCanvas使用兩種可選圖形渲染後端(rendering back-ends)。第一種是XLIB,實現快速圖像顯示,另一種基於Libart類庫,優秀成熟、反抖動,並支持alpha-compositing。GnomeCanvas由於血緣關係,能夠和GTK程序幾乎是無縫的融合。由於我們的程序需要使用圖像的運動過程中的縮放功能,爲了更快的顯示速度,我決定考慮一下使用GnomeCanvas進行優化,並測試。


2、有GnomeCanvas類似的類庫?


有,gEvas,http://www.linuxjournal.com/article/8213中說“Evas library provides a canvas for quickly rendering raster graphics with alpha blending support.” “gEvas is a wrapper and glue library built to allow Evas to be used from GTK+2.x applications easily.” 並有gEvas和gnomecanvas的一些對比測試。 我想等我搞清楚了GnomeCanvas,有餘力再看看gEvas,也對比測試一把,學無止境呀,青春苦短,時間太瘦,指縫太寬。



3、基礎概念

當初沒有系統學習,拿着個例子就勇往直前,以爲能夠輕鬆搞定。只是我在圖像處理的開發經驗不夠,看着一堆的affine、alpha、world coordinates、 canvas coordinates、item coordinates終於暈了。詩人里爾克說:誰此時孤獨,就永遠孤獨。我想到的是:誰此時不懂,就永遠不懂.......


3.1 圖像的alpha通道


Alpha其實是一個決定混合透明度的數值,抄一段網上的說明:假設一幅圖象是A,另一幅透明的圖象是B,那麼透過B去看A,看上去的圖象C就是B和A的混合圖象。

Gnome/GTK程序一般使用GdkPixbuf把圖像數據保存在內存,當圖像格式在GdkPixbuf表示成RGBA/RGB兩種格式的時候,A值就是透明度。GdkPixbuf中數據不一定含有alpha,例如:如果GdkPixbuf數據從jpg文件讀入,是不含alpha通道的,但是從png文件讀入,則包含alpha值。使用下面的代碼行判斷GdkPixbuf是否包含alpha通道。

  g_assert (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
  g_assert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
  g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
  g_assert (gdk_pixbuf_get_n_channels (pixbuf) == 4);

直接操作GdkPixbuf的指針可以修改圖像上任何一點的alpha值
例如:
  guchar *pixels;
  pixels = gdk_pixbuf_get_pixels (pixbuf);
  for (xindex=0;xindex<width;xindex++){
    for(yindex=0;yindex<height;yindex++){
        p = pixels + yindex * rowstride + xindex * n_channels;
        p[3] =0x2F ;           
    }
  }
alpha的取值範圍:(0-255, 0=completely transparent, 255=opaque)

 

3.2GnomeCanvas、GnomeCanvasItem、與GTK的控件的關係 。

首先,GnomeCanvas類庫也是GObject的血統,與GTK可以說是同源。

GnomeCanvas是一個“畫布”對象(GObject的對象,與CPP對象不同),同時,GnomeCanvas 是一種GtkWidget *,可以放到GTK的容器中。畫布上面的繪畫對象是GnomeCanvasItem,例如GnomeCanvasPixbuf 是圖像的對象,GnomeCanvasText 則是文本對象,

GnomeCanvasPolygon是多邊形的對象。GnomeCanvasItem只包含操作對象的方法,各種GnomeCanvasItem子類基本上只定義額外負擔了的屬性。例如GnomeCanvasPixbuf,並未定義額外的操作方法,只定義了下面這些屬性:

  "anchor"                   GtkAnchorType         : Read / Write
  "height"                   gdouble               : Read / Write
  "height-in-pixels"         gboolean              : Read / Write
  "height-set"               gboolean              : Read / Write
  "pixbuf"                   GdkPixbuf*            : Read / Write
  "width"                    gdouble               : Read / Write
  "width-in-pixels"          gboolean              : Read / Write
  "width-set"                gboolean              : Read / Write
  "x"                        gdouble               : Read / Write
  "x-in-pixels"              gboolean              : Read / Write
  "y"                        gdouble               : Read / Write
  "y-in-pixels"              gboolean              : Read / Write

有趣的是GnomeCanvas定義了命名爲GnomeCanvasWidget的GnomeCanvasItem,用以在畫布上嵌入GTK的對象。當然,還有一種用途,就是畫布對象中嵌入“子畫布”。

 

 

3.3 座標變換

world coordinates相當於Window OS下圖形編程的世界座標,是一種無限的、抽象的、邏輯的座標。世界座標使用雙精度浮點數表示。畫屏的時候使用畫布像素座標,該座標叫做canvas coordinates,使用整數來指定像素位置。畫布上每一個元素都有自身的系統座標,該座標叫做item coordinates。item coordinates是一種相對的world coordinates,相對於與本元素左上腳的點的座標值,左上腳的點爲(0.0,0.0)。

 

 

下面描述的方法來自GnomeCanvas的定義。gnome_canvas_w2c()完成從world coordinates到canvas coordinates的轉換,gnome_canvas_c2w()則完成反向轉換。gnome_canvas_w2c_affine(GnomeCanvas *canvas,double affine[6])獲取從world coordinates到canvas coordinates的轉換的仿射變換矩陣。gnome_canvas_w2c_d()和gnome_canvas_w2c()類似,但是以dbouble的類型返回canvas coordinates(避免返回整形時導致的精度丟失)。gnome_canvas_set_pixels_per_unit()能夠設置畫布的縮放比例(每個世界座標單元的畫布像素個數),當設置成1.0的時候兩者是一一對應的,例如[5, 6] 像素單元 在世界座標中則是 [5.0, 6.0]。

3.4仿射變換
仿射平面(或空間)到自身的一類變換,最重要的性質是保持點的共線性(或共面性)以及保持直線的平行性。通常在圖像處理中的旋轉、縮放、切變、反射以及正投影。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章