Cairo 图形指南 (11) —— 图像
2010-04-30 17:04
309 查看
在这一篇里,要讲述图像的处理。先是演示如何在 GTK+ 窗口中显示一幅图像,然后再制造一些特效。
在第一个例子里,显示了一幅图像。
这个示例显示了一幅图片,其尺寸为 300x225,可从这里
下载。这是斯洛伐克西部一个什么地方(Plavecke Podhradie)的中世纪城堡的废墟的一幅照片。
view source
print
?
用一幅 png 图片来创建一份图像外观。出于效率的考虑,应在主函数中调用这个函数。
view source
print
?
基于前面构造的图像外观来创建源与外观,用于图像的绘制。
view source
print
?
绘制图片。
view source
print
?
这个垂帘效果幕后的思想相当简单。图片的高度是 h 个像素,则可对其逐行进行绘制,直至图片完全显示。
view source
print
?
声明两个 cairo 环境,一个与 GtkWindow 相关联,另一个与图片相关联。
view source
print
?
创建一个图像外观,并通过它构造那个与图像相关联的 cairo 环境。
view source
print
?
在初始的空图像中绘制一个矩形,它在循环显示中会增加 1 个像素的高度。采用这种方式创建的图像在后面要作为蒙板来用。
view source
print
?
整幅图像绘制完毕后,停止计时器。
view source
print
?
城堡图像被设置为要被绘制的源,并采用 surface 的 alpha 通道作为蒙板来绘制这个源。
view source
print
?
这个示例的许多细节与上一个示例相似。这次,是将图像分为每 8 行为一个区域。在每次循环中,8 个部分中每个区域增加一个像素高度。通过这种方式创建的图像将再一次作为模板来显示城堡图像。
view source
print
?
这是该示例的主要逻辑,我们逐渐的将线绘制到各区域。
在第一个例子里,显示了一幅图像。
01.
#
include
<cairo.h>
02.
#
include
<gtk/gtk.h>
03.
04.
cairo_surface_t *image;
05.
06.
static
gboolean
07.
on_expose_event(GtkWidget *widget,
08.
GdkEventExpose *event,
09.
gpointer data)
10.
{
11.
cairo_t *cr;
12.
13.
cr = gdk_cairo_create (widget->window);
14.
15.
cairo_set_source_surface(cr,image,
10
,
10
);
16.
cairo_paint(cr);
17.
18.
cairo_destroy(cr);
19.
20.
return
FALSE;
21.
}
22.
23.
24.
int
main(
int
argc,char *argv[])
25.
{
26.
GtkWidget *window;
27.
28.
image = cairo_image_surface_create_from_png(
"plaveckycastle.png"
);
29.
30.
gtk_init(&argc,&argv);
31.
32.
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
33.
34.
g_signal_connect(window,
"expose-event"
,
35.
G_CALLBACK (on_expose_event),NULL);
36.
g_signal_connect(window,
"destroy"
,
37.
G_CALLBACK (gtk_main_quit),NULL);
38.
39.
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
40.
gtk_window_set_default_size(GTK_WINDOW(window),
320
,
250
);
41.
gtk_widget_set_app_paintable(window,TRUE);
42.
43.
gtk_widget_show_all(window);
44.
45.
gtk_main();
46.
47.
cairo_surface_destroy(image);
48.
49.
return
0
;
50.
}
这个示例显示了一幅图片,其尺寸为 300x225,可从这里
下载。这是斯洛伐克西部一个什么地方(Plavecke Podhradie)的中世纪城堡的废墟的一幅照片。
view source
?
1.
image = cairo_image_surface_create_from_png(
"plaveckycastle.png"
);
用一幅 png 图片来创建一份图像外观。出于效率的考虑,应在主函数中调用这个函数。
view source
?
1.
cairo_set_source_surface(cr,image,10,10);
基于前面构造的图像外观来创建源与外观,用于图像的绘制。
view source
?
1.
cairo_paint(cr);
绘制图片。
垂帘效果(Blind Down)
在下面的代码示例中,要垂帘显示图片,就像拉下窗帘的那种效果。view source
?
01.
#include <cairo.h>
02.
#include <gtk/gtk.h>
03.
04.
05.
gboolean timer = TRUE;
06.
cairo_surface_t *image;
07.
08.
09.
static
gboolean
10.
on_expose_event(GtkWidget *widget,
11.
GdkEventExpose *event,
12.
gpointer data)
13.
{
14.
cairo_t *cr;
15.
cairo_t *ic;
16.
17.
cairo_surface_t *surface;
18.
19.
static
gdouble angle = 0;
20.
static
gint image_width = 0;
21.
static
gint image_height = 0;
22.
23.
static
gint w = 0;
24.
static
gint h = 0;
25.
26.
cr = gdk_cairo_create(widget->window);
27.
28.
gint width,height;
29.
gtk_window_get_size(GTK_WINDOW(widget),&width,&height);
30.
31.
image_width = cairo_image_surface_get_width(image);
32.
image_height = cairo_image_surface_get_height(image);
33.
w = image_width;
34.
35.
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,image_width,image_height);
36.
ic = cairo_create(surface);
37.
38.
cairo_rectangle(ic,0,0,w,h);
39.
cairo_fill(ic);
40.
41.
h += 1;
42.
if
( h == image_height) timer = FALSE;
43.
44.
cairo_set_source_surface(cr,image,10,10);
45.
cairo_mask_surface(cr,surface,10,10);
46.
47.
cairo_surface_destroy(surface);
48.
49.
cairo_destroy(cr);
50.
cairo_destroy(ic);
51.
return
FALSE;
52.
}
53.
54.
static
gboolean
55.
time_handler(GtkWidget *widget)
56.
{
57.
if
(widget->window == NULL)
return
FALSE;
58.
59.
if
(!timer)
return
FALSE;
60.
61.
gtk_widget_queue_draw(widget);
62.
return
TRUE;
63.
}
64.
65.
int
main(
int
argc,
char
*argv[])
66.
{
67.
GtkWidget *window;
68.
69.
image = cairo_image_surface_create_from_png(
"plaveckycastle.png"
);
70.
71.
gtk_init(&argc,&argv);
72.
73.
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
74.
75.
g_signal_connect(G_OBJECT(window),
"expose-event"
,
76.
G_CALLBACK(on_expose_event),NULL);
77.
g_signal_connect(G_OBJECT(window),
"destroy"
,
78.
G_CALLBACK(gtk_main_quit),NULL);
79.
80.
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
81.
gtk_window_set_default_size(GTK_WINDOW(window),325,250);
82.
gtk_window_set_title(GTK_WINDOW(window),
"blind down"
);
83.
84.
gtk_widget_set_app_paintable(window,TRUE);
85.
g_timeout_add(15,(GSourceFunc) time_handler,(gpointer) window);
86.
87.
gtk_widget_show_all(window);
88.
89.
gtk_main();
90.
91.
cairo_surface_destroy(image);
92.
93.
return
0;
94.
}
这个垂帘效果幕后的思想相当简单。图片的高度是 h 个像素,则可对其逐行进行绘制,直至图片完全显示。
view source
?
1.
cairo_t *cr;
2.
cairo_t *ic;
声明两个 cairo 环境,一个与 GtkWindow 相关联,另一个与图片相关联。
view source
?
1.
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,image_width,image_height);
2.
ic = cairo_create(surface);
创建一个图像外观,并通过它构造那个与图像相关联的 cairo 环境。
view source
?
1.
cairo_rectangle(ic,0,0,w,h);
2.
cairo_fill(ic);
在初始的空图像中绘制一个矩形,它在循环显示中会增加 1 个像素的高度。采用这种方式创建的图像在后面要作为蒙板来用。
view source
?
1.
h += 1;
2.
if
( h == image_height) timer = FALSE;
整幅图像绘制完毕后,停止计时器。
view source
?
1.
cairo_set_source_surface(cr,image,10,10);
2.
cairo_mask_surface(cr,surface,10,10);
城堡图像被设置为要被绘制的源,并采用 surface 的 alpha 通道作为蒙板来绘制这个源。
光谱效果
将这种效果称为光谱效果,因为作者不知道怎么称呼才好(我感觉叫百叶窗效果更好)。可能你还记得从前的 ZX 光谱计算机,在这种计算机上载入图像时,它就逐渐的被显示出来,下面的示例大致是模仿这种方式。view source
?
001.
#include <cairo.h>
002.
#include <gtk/gtk.h>
003.
004.
005.
gboolean timer = TRUE;
006.
cairo_surface_t *image;
007.
008.
static
gboolean
009.
on_expose_event(GtkWidget *widget,
010.
GdkEventExpose *event,
011.
gpointer data)
012.
{
013.
cairo_t *cr;
014.
cairo_t *ic;
015.
016.
cairo_surface_t *surface;
017.
018.
static
gdouble angle = 0;
019.
static
gint w = 0;
020.
static
gint h = 0;
021.
022.
static
gint image_width = 0;
023.
static
gint image_height = 0;
024.
025.
static
gint count = 0;
026.
027.
cr = gdk_cairo_create(widget->window);
028.
029.
gint width,height;
030.
gtk_window_get_size(GTK_WINDOW(widget),&width,&height);
031.
032.
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,image_width,image_height);
033.
034.
image_width = cairo_image_surface_get_width(image);
035.
image_height = cairo_image_surface_get_height(image);
036.
w = image_width;
037.
038.
ic = cairo_create(surface);
039.
040.
gint i,j;
041.
for
(i = 0; i <= image_height; i+=7) {
042.
for
(j=0 ; j < count; j++) {
043.
cairo_move_to(ic,0,i+j);
044.
cairo_line_to(ic,w,i+j);
045.
}
046.
}
047.
048.
count++;
049.
if
( count == 8) timer = FALSE;
050.
051.
cairo_stroke(ic);
052.
053.
cairo_set_source_surface(cr,image,10,10);
054.
cairo_mask_surface(cr,surface,10,10);
055.
056.
cairo_surface_destroy(surface);
057.
058.
cairo_destroy(cr);
059.
cairo_destroy(ic);
060.
return
FALSE;
061.
}
062.
063.
static
gboolean
064.
time_handler (GtkWidget *widget)
065.
{
066.
if
(widget->window == NULL)
return
FALSE;
067.
068.
if
(!timer)
return
FALSE;
069.
070.
gtk_widget_queue_draw(widget);
071.
return
TRUE;
072.
}
073.
074.
int
main(
int
argc,
char
*argv[])
075.
{
076.
GtkWidget *window;
077.
078.
image = cairo_image_surface_create_from_png(
"plaveckycastle.png"
);
079.
080.
gtk_init(&argc,&argv);
081.
082.
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
083.
084.
g_signal_connect(G_OBJECT(window),
"expose-event"
,
085.
G_CALLBACK(on_expose_event),NULL);
086.
g_signal_connect(G_OBJECT(window),
"destroy"
,
087.
G_CALLBACK(gtk_main_quit),NULL);
088.
089.
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
090.
gtk_window_set_default_size(GTK_WINDOW(window),325,250);
091.
092.
gtk_widget_set_app_paintable(window,TRUE);
093.
g_timeout_add(400,(GSourceFunc) time_handler,(gpointer) window);
094.
095.
gtk_widget_show_all(window);
096.
097.
gtk_main();
098.
099.
cairo_surface_destroy(image);
100.
101.
return
0;
102.
}
这个示例的许多细节与上一个示例相似。这次,是将图像分为每 8 行为一个区域。在每次循环中,8 个部分中每个区域增加一个像素高度。通过这种方式创建的图像将再一次作为模板来显示城堡图像。
view source
?
1.
gint i,j;
2.
for
(i = 0; i <= image_height; i+=7) {
3.
for
(j=0 ; j < count; j++) {
4.
cairo_move_to(ic,0,i+j);
5.
cairo_line_to(ic,w,i+j);
6.
}
7.
}
这是该示例的主要逻辑,我们逐渐的将线绘制到各区域。
相关文章推荐
- Cairo 图形指南 (5) —— 图像
- Cairo 图形指南 (5) —— 图像
- Cairo 图形指南(1) —— 基本绘图
- Cairo 图形指南 (3) —— 变换
- Cairo 图形指南 (3) —— Cairo 后端
- Cairo 图形指南 (3) —— Cairo 后端
- Cairo图形指南(4)
- Cairo 图形指南 (4) —— 裁剪与遮蔽
- Cairo 图形指南 (4) —— 基本绘图
- Cairo图形指南(5)
- Cairo 图形指南 (6) —— 透明
- Cairo 图形指南 (2) —— 文本
- Cairo 图形指南 (6) —— 透明
- Cairo 图形指南 (7) —— 合成
- Cairo图形库编辑指南——介绍
- Cairo图形指南(6)
- Cairo 图形指南 (7) —— 合成
- 游戏玩家的图形显示设置指南(11)(The Gamer's Graphics & Display Settings Guide)
- Cairo 图形指南 (4) —— 基本绘图
- Cairo图形指南(7)--合成