GNOME 平台的2D图形编程(GTK,GDK,Cairo...) 简介 [转]

2023-10-11 01:08

本文主要是介绍GNOME 平台的2D图形编程(GTK,GDK,Cairo...) 简介 [转],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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;

========================================


上 面代码 绘制出来的就是半透明 的图形叠加等效果了,像下面这样。
GNOME 平台的2D图形编程(GTK,GDK,Cairo...) 简介 -  widebright - widebright的个人空间

这篇关于GNOME 平台的2D图形编程(GTK,GDK,Cairo...) 简介 [转]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/184411

相关文章

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

C#多线程编程中导致死锁的常见陷阱和避免方法

《C#多线程编程中导致死锁的常见陷阱和避免方法》在C#多线程编程中,死锁(Deadlock)是一种常见的、令人头疼的错误,死锁通常发生在多个线程试图获取多个资源的锁时,导致相互等待对方释放资源,最终形... 目录引言1. 什么是死锁?死锁的典型条件:2. 导致死锁的常见原因2.1 锁的顺序问题错误示例:不同

PyCharm接入DeepSeek实现AI编程的操作流程

《PyCharm接入DeepSeek实现AI编程的操作流程》DeepSeek是一家专注于人工智能技术研发的公司,致力于开发高性能、低成本的AI模型,接下来,我们把DeepSeek接入到PyCharm中... 目录引言效果演示创建API key在PyCharm中下载Continue插件配置Continue引言

Golang的CSP模型简介(最新推荐)

《Golang的CSP模型简介(最新推荐)》Golang采用了CSP(CommunicatingSequentialProcesses,通信顺序进程)并发模型,通过goroutine和channe... 目录前言一、介绍1. 什么是 CSP 模型2. Goroutine3. Channel4. Channe

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

C#反射编程之GetConstructor()方法解读

《C#反射编程之GetConstructor()方法解读》C#中Type类的GetConstructor()方法用于获取指定类型的构造函数,该方法有多个重载版本,可以根据不同的参数获取不同特性的构造函... 目录C# GetConstructor()方法有4个重载以GetConstructor(Type[]

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06