GTK进阶学习:GTK实现截图功能( 可以指定截图范围 )

按按钮截图,图片保存在当前路径为“save.png”:

#include <gtk/gtk.h>
#include <cairo.h>

/********************************************************
功能:指定窗口区域截图,需要包含头文件cairo.h
参数:
	area: 		需要截图的窗口指针
	x, y, w, h: 截图的范围
	path_name:	保存图片的路径名字,如 "./image/test.png"
返回值:截图的图片pixbuf,失败返回NULL
*********************************************************/
GdkPixbuf *screenshot(GtkWidget *area, int x, int y, int w, int h, char *path_name)
{
	GdkPixbuf *pixbuf = NULL;
	pixbuf = gdk_pixbuf_get_from_drawable(NULL, area->window, NULL,
            x, y, 0, 0, w, h);  //取到矩形区域图片
	if(NULL == pixbuf){	// 如果没有获取成功,结束函数
		printf("gdk_pixbuf_get_from_drawable failed\n");
		return	NULL;
	}

	cairo_surface_t *surface = NULL;
	cairo_t *cr;
	// 创建一个 Cairo 外观
	surface = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32, w, h) ;
	// 一个 Cairo 环境
	cr = cairo_create( surface) ; 

	// 给cr绘图
	gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
	cairo_paint(cr);

	// 截图
	cairo_surface_write_to_png ( surface, path_name ) ;

	// 释放相应资源
	cairo_destroy(cr) ;
	cairo_surface_destroy( surface) ;
	//g_object_unref(pixbuf);

	return pixbuf;
}		

/* 功能:  设置背景图
 * widget: 主窗口
 * w, h:   图片的大小
 * path:  图片路径
 */
void chang_background(GtkWidget *widget, int w, int h, const gchar *path)
{
	gtk_widget_set_app_paintable(widget, TRUE);		//允许窗口可以绘图
	gtk_widget_realize(widget);	

	/* 更改背景图时,图片会重叠
	 * 这时要手动调用下面的函数,让窗口绘图区域失效,产生窗口重绘制事件(即 expose 事件)。
	 */
	gtk_widget_queue_draw(widget);

	GdkPixbuf *src_pixbuf = gdk_pixbuf_new_from_file(path, NULL);	// 创建图片资源对象
	// w, h是指定图片的宽度和高度
	GdkPixbuf *dst_pixbuf = gdk_pixbuf_scale_simple(src_pixbuf, w, h, GDK_INTERP_BILINEAR);

	GdkPixmap *pixmap = NULL;

	/* 创建pixmap图像;
	 * NULL:不需要蒙版;
	 * 123: 0~255,透明到不透明
	 */
	gdk_pixbuf_render_pixmap_and_mask(dst_pixbuf, &pixmap, NULL, 128);
	// 通过pixmap给widget设置一张背景图,最后一个参数必须为: FASLE
	gdk_window_set_back_pixmap(widget->window, pixmap, FALSE);

	// 释放资源
	g_object_unref(src_pixbuf);
	g_object_unref(dst_pixbuf);
	g_object_unref(pixmap);
}

// 按钮"clicked"信号的处理函数
void deal_button(GtkWidget *w, gpointer data)
{
	// 截图,指定窗口区域为(0, 0, 300, 300),在当前路径保存图片为save.png
	screenshot(GTK_WIDGET(data), 0, 0, 300, 300, "save.png");
}

int main( int argc, char *argv[])
{
	gtk_init(&argc, &argv);

	//主窗口操作
	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

	gtk_window_set_title(GTK_WINDOW(window), "设置窗口背景图");
	gtk_widget_set_size_request(window, 500, 450);

	chang_background(window, 500, 400, "image.jpg");	// 设置窗口背景图

	GtkWidget *table = gtk_table_new(3, 3, TRUE);   // 表格布局,3行3列
	gtk_container_add(GTK_CONTAINER(window), table); // 容器加入窗口

	// 截图按钮
	GtkWidget *button = gtk_button_new_with_label("截图");
	gtk_table_attach_defaults(GTK_TABLE(table), button, 2, 3, 2, 3);
	// 处理按钮的信号,把窗口指针window传给回调函数deal_button()
 	g_signal_connect(button, "clicked", G_CALLBACK(deal_button), window);

	gtk_widget_show_all(window); // 显示所有部件

	gtk_main();

	return 0;
}

程序运行效果图:

截出来的图片:

源代码下载请点此处。

时间: 2025-01-06 05:04:48

GTK进阶学习:GTK实现截图功能( 可以指定截图范围 )的相关文章

GTK进阶学习:设置窗口背景图(可指定其大小)

设置窗口背景图(可指定其大小): #include <gtk/gtk.h> /* 功能: 设置背景图 * widget: 主窗口 * w, h: 图片的大小 * path: 图片路径 */ void chang_background(GtkWidget *widget, int w, int h, const gchar *path) { gtk_widget_set_app_paintable(widget, TRUE); //允许窗口可以绘图 gtk_widget_realize(widg

GTK进阶学习:绘图事件

GTK界面只要有图片的地方,其底层实际上是通过绘图实现的,所以,我们很有必要学习一下绘图,这里我们使用 Cairo 进行相应的绘图操作. Cairo是用于绘制二维矢量图形的跨平台图形库,采用 C 语言实现,又被许多其它计算机语言所绑定.我们可以使用Cairo库在窗口中绘图,也可以用于生成PNG图片.PDF.PostScript.SVG文件.Cairo同时也是自由软件库,自GTK+2.8版本开始,Cairo成为GTK+库的一部分. 绘图实际上也是事件的一种,GTK中,绘图事件也叫曝光事件. 绘图时

GTK进阶学习:定时器

定时器在应用编程里用得很广,我们手机里的闹钟,幻灯片播放图片等应用都用到定时器.定时器,每隔一段时间干一件事(程序里表现为调用一个函数),像闹钟,每隔一天响一次. 定时器的创建: guint g_timeout_add(guint interval, GSourceFunc function, gpointer data); interval:设置的时间间隔,以毫秒为单位( 1000即为1秒 ) function:回调函数的名字 data:给回调函数传的参数 返回值:定时器id号 使用实例: g

GTK进阶学习:属性改变事件

当窗口初始化,被移动或拉伸时,会触发属性改变事件. 属性改变事件产生的信号:configure_event 其回调函数的定义如下: gboolean callback( GtkWidget *widget, GdkEventConfigure *event, gpointer data ) { event:属性事件结构体变量,系统内部的变量,不是用户传参的 event->x,event->y:窗口的起点坐标 event->width,event->height:窗口的大小 } 以下

GTK进阶学习:事件盒子

有些控件( 如:标签GtkLabel,图片控件GtkImage 等),不响应GDK事件,相当于鼠标在其上面点击,它是捕获不到的.用户通过事件盒子可以解决这个问题. 事件盒子给控件提供一个GDK窗口来捕获事件.我们把控件放在事件盒子里,当我们用鼠标点击这个控件时,这个事件盒子就能捕获到点击的状态. 事件盒子的创建: GtkWidget *gtk_event_box_new(void); 返回值:事件盒子指针 把控件添加到事件盒子里: void gtk_container_add(GtkContai

GTK进阶学习:鼠标事件

鼠标事件,可以理解为操作鼠标的动作.对于窗口而言,用户操作鼠标,窗口检测到鼠标的操作( 产生一个信号 ),然后去做相应处理( 调用其规定的回调函数 ),即可认为是鼠标事件,还是信号与回调函数的知识点. 信号与回调函数的使用请点击此处. 窗口默认不接收鼠标的操作,需要手动添加让其接收. 设置控件捕获(接收)相应的事件: void gtk_widget_add_events( GtkWidget *widget, gint events ); widget:控件 events:事件类型,它是GdkE

GTK入门学习:信号与回调函数

前面我们学习的GTK界面都是静态的,我们按下按钮它是没有响应的,如何让它有响应呢?接下来我们一起学习GTK的信号与回调函数. GTK采用了信号与回调函数来处理窗口外部传来的事件.消息或信号.当信号发生时,程序自动调用为信号连接的回调函数. 学习应用编程,我们会经常接触到"信号"这个名词.GTK中的"信号"实际上是一种软件中断."中断"在我们生活中经常遇到,譬如,我正在房间里打游戏,突然送快递的来了,把正在玩游戏的我给"中断"了

Selenium2学习-023-WebUI自动化实战实例-021-获取浏览器显示区域大小,通过 WebDriver 截图功能

之前的博文 020-JavaScript 在 Selenium 自动化中的应用实例之二(获取浏览器显示区域大小) 简述了通过 JavaScript 获取浏览器显示区域大小,此文将简述另一种获取浏览器显示区域大小的方法,即通过 WebDriver 的截图功能,获取显示区域的截图,通过截图的大小获取浏览器显示区域的大小. 直接上码了,敬请小主们参阅,若有不足之处,敬请大神指正,不胜感激! 1 /** 2 * Get width and height about display screen area

42步进阶学习—让你成为优秀的Java大数据科学家!

作者 灯塔大数据 本文转自公众号灯塔大数据(DTbigdata),转载需授权 如果你对各种数据类的科学课题感兴趣,你就来对地方了.本文将给大家介绍让你成为优秀数据科学家的42个步骤.深入掌握数据准备,机器学习,SQL数据科学等. 本文将这42步骤分为六个部分, 前三个部分主要讲述从数据准备到初步完成机器学习的学习过程,其中包括对理论知识的掌握和Python库的实现. 第四部分主要是从如何理解的角度讲解深入学习的方法.最后两部分则是关于SQL数据科学和NoSQL数据库. 接下来让我们走进这42步进