1、用到的库主要是
GDK的函数库 http://library.gnome.org/devel/gdk/stable/
和 cairo库 http://cairographics.org/documentation/
GTK+ 底层自己也就是用的cairo了。
基本的绘图 点,线、弧 、多变形都可以在上面说的两个库里面找到
比如 gdk_draw_line 等函数。。。
2、GdkPixbuf 就是一个Bitmap 的封装类,很多绘图操作都要通过它,
(1) 从文件加载 png jpeg或者bmp图形。比较好的是支持多种格式的。
GdkPixbuf * widebright_png = gdk_pixbuf_new_from_file ("widebright.png",&error);
保存到文件
gdk_pixbuf_save(pixbuf, "screenshot.jpg", "jpeg", NULL, "quality", "100",NULL);
(2) 把 GdkPixbuf 里面图形信息绘制到显示窗体,
gdk_draw_pixbuf ((GdkDrawable *) gdk_window,
gc,
pixbuf,
0,
0,
0,
0,
w,
h,
GDK_RGB_DITHER_NONE ,
1,
1);
(3) 获取窗体上面的 图形到GdkPixbuf
GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, root_window, NULL,
0, 0, 0, 0, w, h); // 抓图
3、GtkWindow 到 GdkWindow 。因为图形操作都是通过 GdkWindow 来进行的,所以经常要从Gtk控件的到它的GdkWindow,才能进行绘图操作。
其实就是通过GtkWidget结构的 window成员
GdkWindow * gdk_window =GTK_WIDGET( window)->window;
4。 抓屏
这个很简单,获取到root窗体的 GdkWindow 就可以用上面的办法来操作了。
GdkScreen *screen = gdk_screen_get_default();
//GdkWindow * rootWindow =gdk_screen_get_root_window(screen);
GdkWindow * root_window = gdk_get_default_root_window (); //这个和上面那个函数一样的
if (!root_window )
{
return TRUE;
}
int w = gdk_screen_get_width(screen);
int h = gdk_screen_get_height(screen);
5。 绘制
可以自己处理 expose_event signal消息, 其实就相当于 windows平台的WM_PAINT消息
如果在其他地方绘制图形,又想有后台缓 存的话,可以调用这两个函数
gdk_window_begin_paint_rect ((GdkDrawable *)gdk_window,&rect);
gdk_window_end_paint ((GdkDrawable *)gdk_window);
6、cairo 库绘制的话也很方便
直接使用 gdk_cairo_create 来从 GdkWindow来得到一个 cairo_t 绘图环境就可以画图了,
cairo_t * gdk_cairo_create (GdkDrawable *drawable);
void gdk_cairo_set_source_color (cairo_t *cr,
const GdkColor *color);
void gdk_cairo_set_source_pixbuf (cairo_t *cr,
const GdkPixbuf *pixbuf,
double pixbuf_x,
gdk_cairo_set_source_pixbuf 可以把GdkPixbuf 里面图形传到 cairo绘图表面上去。
cairo有趣的地方是他可以设置 mask 蒙版,还有 “线性渐变” “径状辐射渐变”等,可以产生半透明的模糊效果了。
不过的东西,蒙版也都是不错的。 还可以方便的设置 alpha通道进行半透明绘制等。
下 面的是乱七八糟的一个例子,看懂了一般的绘图都不成问题了,哈哈,忘记了的时候还可以来看一下。
===========================================
GdkWindow * gdk_window = window->window;
// GdkScreen *screen1 = gdk_screen_get_default();
// GdkColormap * colormap = gdk_screen_get_rgba_colormap(screen1);
// gtk_widget_set_colormap(window, colormap);
cairo_t *cr2 = gdk_cairo_create(gdk_window);
//gdk_pixbuf_new_from_file方法 才能保存 alpha通道的透明信息,
//cairo_image_surface_create_from_png 好像不行
GError * error =NULL;
GdkPixbuf * widebright_png = gdk_pixbuf_new_from_file ("widebright.png",&error);
cairo_surface_t *image = cairo_image_surface_create_from_png("Screenshot.png"); // cairo函数读取png文件
cairo_surface_t *icon = cairo_image_surface_create_from_png("widebrigh.png"); // cairo函数读取png文件
cairo_t *cr = cairo_create(image);
///默认是CAIRO_OPERATOR_OVER draw source layer on top of destination layer (bounded)
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); //replace destination layer (bounded)
cairo_set_operator(cr2, CAIRO_OPERATOR_SOURCE); //replace destination layer (bounded)
cairo_pattern_t *linpat, *radpat;
linpat = cairo_pattern_create_linear (0, 0, 0, 100);
cairo_pattern_add_color_stop_rgb (linpat, 0, 0, 0.8, 0.8);
cairo_pattern_add_color_stop_rgb (linpat, 100, 0.8, 0.8, 0.0);
radpat = cairo_pattern_create_radial (100,100, 0, 100, 100, 100);
cairo_pattern_add_color_stop_rgba (radpat, 0, 0, 0, 0, 1);
cairo_pattern_add_color_stop_rgba (radpat, 100, 0, 0, 0, 0);
//cairo_set_source (cr, linpat);
GdkGC * gc = gdk_gc_new ( (GdkDrawable *) gdk_window);
if (!gc) {
gtk_label_set_text(label_message,"error");
return TRUE;
}
GdkColor color;
color.red = 0;
color.green = 0;
color.blue = 30000;
gdk_gc_set_rgb_bg_color(gc , &color);
gdk_gc_set_rgb_fg_color(gc , &color);
GdkScreen *screen = gdk_screen_get_default();
//GdkWindow * rootWindow =gdk_screen_get_root_window(screen);
GdkWindow * root_window = gdk_get_default_root_window (); //这个和上面那个函数一样的
if (!root_window )
{
return TRUE;
}
int w = gdk_screen_get_width(screen);
int h = gdk_screen_get_height(screen);
GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, root_window, NULL,
0, 0, 0, 0, w, h); // 抓图
//gdk_pixbuf_save(pixbuf, "screenshot.jpg", "jpeg", NULL, "quality", "100",
// NULL); // 将图片存为jpg格式
GdkRectangle rect;
rect.x =0;
rect.y =0;
rect.width = w;
rect.height =h;
//文档说调用这个会准备好后台缓冲区,绘图时不闪烁。 gdk_window_end_paint后图形就一次性显示
//不调用这个绘图时就一步一步的来,马上显示在屏幕上
//gdk_window_begin_paint_rect ((GdkDrawable *)gdk_window,&rect);
/*
typedef enum
{
GDK_RGB_DITHER_NONE,
GDK_RGB_DITHER_NORMAL,
GDK_RGB_DITHER_MAX
} GdkRgbDither;
*/
//直接调用 gdk_draw_drawable () 从 root_window 到 gdk_window的复制不行,
//可能需要转换成RGB(A) 放到GdkPixbuf 里面才行吧
/*
gdk_draw_pixbuf ((GdkDrawable *) gdk_window,
gc,
pixbuf,
0,
0,
0,
0,
w,
h,
GDK_RGB_DITHER_NONE ,
1,
1);
*/
gdk_cairo_set_source_pixbuf(cr ,pixbuf,0,0);
cairo_paint_with_alpha (cr, 0.65);
gdk_cairo_set_source_pixbuf(cr ,widebright_png,0,0);
cairo_paint_with_alpha (cr, 0.5);
cairo_mask (cr, radpat);
cairo_set_source_surface(cr2, image, 0, 0);
cairo_paint(cr2);
cairo_destroy(cr2);
cairo_destroy(cr);
g_object_unref(pixbuf); // pixbuf是gdk_pixbuf_get_from_drawable新创建的,要释放
//gdk_draw_rectangle((GdkDrawable *) gdk_window, gc ,
// TRUE , 0 , 0 ,
// 500 ,
// 500);
//gdk_window_end_paint ((GdkDrawable *)gdk_window);
//gdk_window_invalidate_rect (gdk_window,&rect,FALSE);
//gdk_window_clear (gdk_window);
g_object_unref(gc);
return TRUE;
========================================
上 面代码 绘制出来的就是半透明 的图形叠加等效果了,像下面这样。
和 cairo库 http://cairographics.org/documentation/
GTK+ 底层自己也就是用的cairo了。
基本的绘图 点,线、弧 、多变形都可以在上面说的两个库里面找到
比如 gdk_draw_line 等函数。。。
2、GdkPixbuf 就是一个Bitmap 的封装类,很多绘图操作都要通过它,
(1) 从文件加载 png jpeg或者bmp图形。比较好的是支持多种格式的。
GdkPixbuf * widebright_png = gdk_pixbuf_new_from_file ("widebright.png",&error);
保存到文件
gdk_pixbuf_save(pixbuf, "screenshot.jpg", "jpeg", NULL, "quality", "100",NULL);
(2) 把 GdkPixbuf 里面图形信息绘制到显示窗体,
gdk_draw_pixbuf ((GdkDrawable *) gdk_window,
gc,
pixbuf,
0,
0,
0,
0,
w,
h,
GDK_RGB_DITHER_NONE ,
1,
1);
(3) 获取窗体上面的 图形到GdkPixbuf
GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, root_window, NULL,
0, 0, 0, 0, w, h); // 抓图
3、GtkWindow 到 GdkWindow 。因为图形操作都是通过 GdkWindow 来进行的,所以经常要从Gtk控件的到它的GdkWindow,才能进行绘图操作。
其实就是通过GtkWidget结构的 window成员
GdkWindow * gdk_window =GTK_WIDGET( window)->window;
4。 抓屏
这个很简单,获取到root窗体的 GdkWindow 就可以用上面的办法来操作了。
GdkScreen *screen = gdk_screen_get_default();
//GdkWindow * rootWindow =gdk_screen_get_root_window(screen);
GdkWindow * root_window = gdk_get_default_root_window (); //这个和上面那个函数一样的
if (!root_window )
{
return TRUE;
}
int w = gdk_screen_get_width(screen);
int h = gdk_screen_get_height(screen);
5。 绘制
可以自己处理 expose_event signal消息, 其实就相当于 windows平台的WM_PAINT消息
如果在其他地方绘制图形,又想有后台缓 存的话,可以调用这两个函数
gdk_window_begin_paint_rect ((GdkDrawable *)gdk_window,&rect);
gdk_window_end_paint ((GdkDrawable *)gdk_window);
6、cairo 库绘制的话也很方便
直接使用 gdk_cairo_create 来从 GdkWindow来得到一个 cairo_t 绘图环境就可以画图了,
cairo_t * gdk_cairo_create (GdkDrawable *drawable);
void gdk_cairo_set_source_color (cairo_t *cr,
const GdkColor *color);
void gdk_cairo_set_source_pixbuf (cairo_t *cr,
const GdkPixbuf *pixbuf,
double pixbuf_x,
gdk_cairo_set_source_pixbuf 可以把GdkPixbuf 里面图形传到 cairo绘图表面上去。
cairo有趣的地方是他可以设置 mask 蒙版,还有 “线性渐变” “径状辐射渐变”等,可以产生半透明的模糊效果了。
不过的东西,蒙版也都是不错的。 还可以方便的设置 alpha通道进行半透明绘制等。
下 面的是乱七八糟的一个例子,看懂了一般的绘图都不成问题了,哈哈,忘记了的时候还可以来看一下。
===========================================
GdkWindow * gdk_window = window->window;
// GdkScreen *screen1 = gdk_screen_get_default();
// GdkColormap * colormap = gdk_screen_get_rgba_colormap(screen1);
// gtk_widget_set_colormap(window, colormap);
cairo_t *cr2 = gdk_cairo_create(gdk_window);
//gdk_pixbuf_new_from_file方法 才能保存 alpha通道的透明信息,
//cairo_image_surface_create_from_png 好像不行
GError * error =NULL;
GdkPixbuf * widebright_png = gdk_pixbuf_new_from_file ("widebright.png",&error);
cairo_surface_t *image = cairo_image_surface_create_from_png("Screenshot.png"); // cairo函数读取png文件
cairo_surface_t *icon = cairo_image_surface_create_from_png("widebrigh.png"); // cairo函数读取png文件
cairo_t *cr = cairo_create(image);
///默认是CAIRO_OPERATOR_OVER draw source layer on top of destination layer (bounded)
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); //replace destination layer (bounded)
cairo_set_operator(cr2, CAIRO_OPERATOR_SOURCE); //replace destination layer (bounded)
cairo_pattern_t *linpat, *radpat;
linpat = cairo_pattern_create_linear (0, 0, 0, 100);
cairo_pattern_add_color_stop_rgb (linpat, 0, 0, 0.8, 0.8);
cairo_pattern_add_color_stop_rgb (linpat, 100, 0.8, 0.8, 0.0);
radpat = cairo_pattern_create_radial (100,100, 0, 100, 100, 100);
cairo_pattern_add_color_stop_rgba (radpat, 0, 0, 0, 0, 1);
cairo_pattern_add_color_stop_rgba (radpat, 100, 0, 0, 0, 0);
//cairo_set_source (cr, linpat);
GdkGC * gc = gdk_gc_new ( (GdkDrawable *) gdk_window);
if (!gc) {
gtk_label_set_text(label_message,"error");
return TRUE;
}
GdkColor color;
color.red = 0;
color.green = 0;
color.blue = 30000;
gdk_gc_set_rgb_bg_color(gc , &color);
gdk_gc_set_rgb_fg_color(gc , &color);
GdkScreen *screen = gdk_screen_get_default();
//GdkWindow * rootWindow =gdk_screen_get_root_window(screen);
GdkWindow * root_window = gdk_get_default_root_window (); //这个和上面那个函数一样的
if (!root_window )
{
return TRUE;
}
int w = gdk_screen_get_width(screen);
int h = gdk_screen_get_height(screen);
GdkPixbuf * pixbuf = gdk_pixbuf_get_from_drawable(NULL, root_window, NULL,
0, 0, 0, 0, w, h); // 抓图
//gdk_pixbuf_save(pixbuf, "screenshot.jpg", "jpeg", NULL, "quality", "100",
// NULL); // 将图片存为jpg格式
GdkRectangle rect;
rect.x =0;
rect.y =0;
rect.width = w;
rect.height =h;
//文档说调用这个会准备好后台缓冲区,绘图时不闪烁。 gdk_window_end_paint后图形就一次性显示
//不调用这个绘图时就一步一步的来,马上显示在屏幕上
//gdk_window_begin_paint_rect ((GdkDrawable *)gdk_window,&rect);
/*
typedef enum
{
GDK_RGB_DITHER_NONE,
GDK_RGB_DITHER_NORMAL,
GDK_RGB_DITHER_MAX
} GdkRgbDither;
*/
//直接调用 gdk_draw_drawable () 从 root_window 到 gdk_window的复制不行,
//可能需要转换成RGB(A) 放到GdkPixbuf 里面才行吧
/*
gdk_draw_pixbuf ((GdkDrawable *) gdk_window,
gc,
pixbuf,
0,
0,
0,
0,
w,
h,
GDK_RGB_DITHER_NONE ,
1,
1);
*/
gdk_cairo_set_source_pixbuf(cr ,pixbuf,0,0);
cairo_paint_with_alpha (cr, 0.65);
gdk_cairo_set_source_pixbuf(cr ,widebright_png,0,0);
cairo_paint_with_alpha (cr, 0.5);
cairo_mask (cr, radpat);
cairo_set_source_surface(cr2, image, 0, 0);
cairo_paint(cr2);
cairo_destroy(cr2);
cairo_destroy(cr);
g_object_unref(pixbuf); // pixbuf是gdk_pixbuf_get_from_drawable新创建的,要释放
//gdk_draw_rectangle((GdkDrawable *) gdk_window, gc ,
// TRUE , 0 , 0 ,
// 500 ,
// 500);
//gdk_window_end_paint ((GdkDrawable *)gdk_window);
//gdk_window_invalidate_rect (gdk_window,&rect,FALSE);
//gdk_window_clear (gdk_window);
g_object_unref(gc);
return TRUE;
========================================
上 面代码 绘制出来的就是半透明 的图形叠加等效果了,像下面这样。
![GNOME 平台的2D图形编程(GTK,GDK,Cairo...) 简介 - widebright - widebright的个人空间](http://img.bimg.126.net/photo/JuNSwTrtS_TuMO9L37NZsA==/1132092356331136122.jpg)