Cairo 图形指南 (6) —— 透明_第1页
Cairo 图形指南 (6) —— 透明_第2页
Cairo 图形指南 (6) —— 透明_第3页
Cairo 图形指南 (6) —— 透明_第4页
Cairo 图形指南 (6) —— 透明_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Cairo 图形指南 (6) 透明这一篇讲述有关透明的一些基本知识,并提供两个有趣的透明效果。透明是透过某种材质的可见度。理解透明最简单的方式就是想像一下玻璃或者水。从技术上讲,光线可以穿过玻璃,因此我们可以看到玻璃之后的物体。在计算机图形学中,可以使用alpha 混合方式来实现透明效果。Alpha 混合,是通过将图像与背景组合实现部分透明的视觉效果。混合过程中使用了一种叫做 alpha 通道的东西。Alpha 通道在图形文件格式中是一个 8 位的层,用于表示图片的透明性。每个像素所包含的这个各额外的 8 位数字提供了一个蒙板,可以表达 256 个层次的透明度。透明的矩形第一个例子,

2、绘制了 10 个不同透明程度的矩形。#include <cairo.h>#include <gtk/gtk.h>static gbooleanon_expose_event (GtkWidget * widget,                 GdkEventExpose * event, gpointer data)        cairo_t *cr;        cr

3、= gdk_cairo_create (widget->window);        gint i;        for (i = 1; i <= 10; i+)                 cairo_set_source_rgba (cr, 0, 0, 1, i * 0.1);   

4、            cairo_rectangle (cr, 50 * i, 20, 40, 40);                cairo_fill (cr);                cairo_destroy (cr);      

5、0; return FALSE;intmain (int argc, char *argv)        GtkWidget *window;        gtk_init (&argc, &argv);        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);        g_sign

6、al_connect (G_OBJECT (window), "expose-event",                          G_CALLBACK (on_expose_event), NULL);        g_signal_connect (G_OBJECT (window), "d

7、estroy",                          G_CALLBACK (gtk_main_quit), NULL);        gtk_window_set_position (GTK_WINDOW (window),                  &

8、#160;              GTK_WIN_POS_CENTER);        gtk_window_set_default_size (GTK_WINDOW (window), 590, 90);        gtk_window_set_title (GTK_WINDOW (window), "transparency"); 

9、      gtk_widget_set_app_paintable (window, TRUE);        gtk_widget_show_all (window);        gtk_main ();        return 0;cairo_set_source_rgba () 函数有一个可选的 alpha 参数,用于提供透明色支持。 gint i; 

10、;       for (i = 1; i <= 10; i+)                 cairo_set_source_rgba (cr, 0, 0, 1, i * 0.1);                cairo_rectangle (cr, 50 * i

11、, 20, 40, 40);                cairo_fill (cr);        这段代码创建 10 个矩形,其 alpha 值从 0.1 递增到 1。淡出的效果在下一个示例中,实现对一幅图片的淡出处理。这幅图片会逐渐变得越来越透明直至看不见。#include <cairo.h>#include <gtk/gtk.h>cairo_surface_t *image;static&

12、#160;gbooleanon_expose_event (GtkWidget * widget,                 GdkEventExpose * event, gpointer data)        cairo_t *cr;        cr = gdk_cairo_create (widget->window);       

13、0;static double alpha = 1;        double const delta = 0.01;        cairo_set_source_surface (cr, image, 10, 10);        cairo_paint_with_alpha (cr, alpha);        a

14、lpha -= delta;        if (alpha <= 0)                timer = FALSE;        cairo_destroy (cr);        return FALSE;static gbooleantime_handler (GtkWidge

15、t * widget)        if (widget->window = NULL)                return FALSE;        gtk_widget_queue_draw (widget);        return TRUE;intmain (int a

16、rgc, char *argv)        GtkWidget *window;        GtkWidget *darea;        gint width, height;        image = cairo_image_surface_create_from_png ("tuz.png");        width = c

17、airo_image_surface_get_width (image);        height = cairo_image_surface_get_height (image);        gtk_init (&argc, &argv);        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);        darea

18、 = gtk_drawing_area_new ();        gtk_container_add (GTK_CONTAINER (window), darea);        g_signal_connect (darea, "expose-event",                         &#

19、160;G_CALLBACK (on_expose_event), NULL);        g_signal_connect (window, "destroy",                          G_CALLBACK (gtk_main_quit), NULL);       

20、; gtk_window_set_position (GTK_WINDOW (window),                                 GTK_WIN_POS_CENTER);        gtk_window_set_default_size (GTK_WINDOW (window), width + 20,&

21、#160;                                    height + 20);        gtk_window_set_title (GTK_WINDOW (window), "fade out");        g_timeout_add&#

22、160;(50, (GSourceFunc) time_handler,                       (gpointer) window);        gtk_widget_show_all (window);        gtk_main ();        cairo_s

23、urface_destroy (image);        return 0;在这一示例中,显示了一幅渐渐淡出的图片。所使用的图片是 Linux kernel 的新 Logo,详见 LinuxToy 网站的介绍。   image = cairo_image_surface_create_from_png ("tuz.png");出于对程序运行效率的考虑,图像外观的创建在主函数中进行。  cairo_set_source_surface 

24、;(cr, image, 10, 10);将载入的图片设置为源 (source)。   cairo_paint_with_alpha (cr, alpha);调用函数 cairo_paint_with_alpha () 来实现图片淡出效果,该函数使用透明度作为蒙板。       alpha -= delta;在每次响应 expose 事件的处理过程中,进行透明度的值递减。 if (alpha <= 0)         

25、       alpha = 1;当透明度为 0 时,意味着图片是完全透明的。这时,再将透明度置为 1,即将图片复原为不透明状态。这样做的目的是让图片周而复始、痛不欲生的淡出着。  g_timeout_add (50, (GSourceFunc) time_handler, (gpointer) window);创建一个计时器,其回调函数为 time_handler (),每隔 50ms 便会被调用一次。static gbooleantime_handler (GtkWidg

26、et * widget)        if (widget->window = NULL)                return FALSE;        gtk_widget_queue_draw (widget);        return TRUE;time_handler () 函数的实现,它

27、的主要作用是调用 gtk_widget_queue_draw () 函数,实现窗口的重绘 (发出 expose 事件)。当该函数返回值为 FALSE 时,计时器便停止工作。        if (widget->window = NULL)                return FALSE;这两行代码看上去有点多余。但是考虑在计时器的时间间隔很小的情况下 (譬如 5ms),如果关闭窗口,这时进程尚未完全销毁,不过窗

28、口已经被 destroy 了。这时,这两行代码可以防止计时器回调函数继续工作而引起的程序崩溃。“等待”的演示下面的示例,使用透明效果制作了一个“等待”状态的演示,是通过绘制 8 条依次消隐淡出的线,模拟一条线的运动过程。像这样的效果通常被用于通知用户耐心地等待一个隐藏在屏幕之后漫长的任务的完成。在网上看视频时,经常可以看到类似的“等待”。#include <cairo.h>#include <gtk/gtk.h>#include <math.h>static gushort count = 0;static gbooleanon

29、_expose_event (GtkWidget * widget,                 GdkEventExpose * event, gpointer data)        cairo_t *cr;        cr = gdk_cairo_create (widget->window);        static g

30、double const trs88 =                 0.0, 0.15, 0.30, 0.5, 0.65, 0.80, 0.9, 1.0,                1.0, 0.0, 0.15, 0.30, 0.5, 0.65,&#

31、160;0.8, 0.9,                0.9, 1.0, 0.0, 0.15, 0.3, 0.5, 0.65, 0.8,                0.8, 0.9, 1.0, 0.0, 0.15, 0.3, 0.5, 0.65,  &

32、#160;             0.65, 0.8, 0.9, 1.0, 0.0, 0.15, 0.3, 0.5,                0.5, 0.65, 0.8, 0.9, 1.0, 0.0, 0.15, 0.3,         

33、       0.3, 0.5, 0.65, 0.8, 0.9, 1.0, 0.0, 0.15,                0.15, 0.3, 0.5, 0.65, 0.8, 0.9, 1.0, 0.0,               

34、 gint width, height;        gtk_window_get_size (GTK_WINDOW (widget), &width, &height);        cairo_translate (cr, width / 2, height / 2);        gint i = 0;        for (i

35、 = 0; i < 8; i+)                 cairo_set_line_width (cr, 3);                cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);                cairo_s

36、et_source_rgba (cr, 0, 0, 0, trscount % 8i);                cairo_move_to (cr, 0.0, -10.0);                cairo_line_to (cr, 0.0, -40.0);       

37、         cairo_rotate (cr, M_PI / 4);                cairo_stroke (cr);                cairo_destroy (cr);        return FALSE;static gboole

38、antime_handler (GtkWidget * widget)        count += 1;        gtk_widget_queue_draw (widget);        return TRUE;intmain (int argc, char *argv)        GtkWidget *window; 

39、       GtkWidget *darea;        gtk_init (&argc, &argv);        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);        g_signal_connect (G_OBJECT (window), "expose-event",   

40、;                       G_CALLBACK (on_expose_event), NULL);        g_signal_connect (G_OBJECT (window), "destroy",                   

41、      G_CALLBACK (gtk_main_quit), NULL);        gtk_window_set_position (GTK_WINDOW (window),                                 GTK_WIN_POS_CENTER);  &#

42、160;     gtk_window_set_default_size (GTK_WINDOW (window), 250, 150);        gtk_window_set_title (GTK_WINDOW (window), "waiting demo");        gtk_widget_set_app_paintable (window, TRUE); 

43、      gtk_widget_show_all (window);        g_timeout_add (100, (GSourceFunc) time_handler,                       (gpointer) window);        gtk_main (

44、);        return 0; 方法比较笨,就是绘制 8 条不同透明度的线。        static gdouble const trs88 =                 0.0, 0.15, 0.30, 0.5, 0.65, 0.80, 0.9, 1

45、.0,                1.0, 0.0, 0.15, 0.30, 0.5, 0.65, 0.8, 0.9,                0.9, 1.0, 0.0, 0.15, 0.3, 0.5, 0.65, 0.8,                0.8, 0.9, 1.0, 0.0, 0.15, 

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论