項目中需要插入圖片,並旋轉任意角度。我用的GTK版本爲windows32bit 2.24,是從官網下的,這版的API中關於rotate pixbuf的api只有一個簡單的旋轉90°倍數的函數:gdk_pixbuf_rotate_simple (),沒有旋轉任意角度的函數。google了一天,終於解決了。方式如下:
STEP 1
搜到了這個bug,他的附件實現了旋轉任意角度,但是這個附件文件不全,我添加了一個gdk-pixbuf-private.h文件(從這裏找的)。並修改了這幾個文件的#include語句,因爲他提供的patch原本是編譯gtk時使用的,但是我用的gtk是已經編譯好了的,無法自己重新編譯,因此必須把#include語句改了,這樣把這個patch當成我自己項目的代碼用就可以了。
STEP 2
把patch中的那幾個.c.h文件放到同一個make目錄下,編譯運行patch自帶的demo,測試效果如下圖:
上圖是運行demo菜單的image的結果,it works!
patch API說明:
gdk_pixbuf_rotate_matrix_開頭的都是一些矩陣工具方法,不重要。
最重要的是這個函數
void gdk_pixbuf_rotate (GdkPixbuf* dst, gdouble dst_x, gdouble dst_y, gdouble* matrix, GdkPixbuf* src, gdouble src_center_x, gdouble src_center_y, gint* result_rect_x, gint* result_rect_y, gint* result_rect_width, gint* result_rect_height, GdkInterpType interp_type);
這個函數把src pixbuf通過rotate matrix轉換後寫到dst pixbuf中,
dst: 目標pixbuf
dst_x: 目標pixbuf的中心
dst_y: 目標pixbuf的中心
matrix: 轉換矩陣
s r c: 源pixbuf
src_center_x: 源pixbuf的中心
src_center_y: 源pixbuf的中心
result_rect_開頭的四個參數: 旋轉後圖形的座標,以目標pixbuf坐上角爲座標系原點。寬高
調用方法可以參考demo,或我的代碼片
段:
MyPicture *picture = MY_PICTURE(self); MyPicturePrivate* priv = MY_PICTURE_GET_PRIVATE (picture); GdkRectangle rect; if (priv->pixbuf) g_object_unref (priv->pixbuf); priv->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, picture->rotateSideLen, picture->rotateSideLen); gdk_pixbuf_fill (priv->pixbuf, 0); gdouble m[4]; gdk_pixbuf_rotate_martix_fill_for_rotation(m, picture->angle); gdk_pixbuf_rotate (priv->pixbuf, picture->rotateSideLen/2, picture->rotateSideLen/2, m, priv->orignPixbuf, picture->orignWidth/2, picture->orignHeight/2, &rect.x, &rect.y, &rect.width, &rect.height, GDK_INTERP_NEAREST); gdk_draw_pixbuf (appState->pixmap, appState->drawingArea->style->white_gc, priv->pixbuf, 0, 0, picture->rotateX + appState->orignX, picture->rotateY + appState->orignY, -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0);
由於這個patch只支持GDK_INTERP_NEAREST,所以旋轉後精度下降的比較厲害,變糙了。哪位同學發現更好的解決方法,請留言,謝謝~
PS: 沒有用cairo處理圖片,是因爲cairo在處理png時,在我的項目中透明的地方都變成黑色了(原因未知,我是用cairo往pixmap上畫的),而且cairo只支持png,不支持jpg等等,於是索性不用cairo畫圖片了。