渐变
最后修改于 2023 年 7 月 17 日
在本部分的 Cairo 图形教程中,我们介绍渐变。我们提到了线性渐变和径向渐变。
在计算机图形学中,渐变是从浅到深或从一种颜色到另一种颜色的平滑混合。在二维绘图程序和绘画程序中,渐变用于创建色彩鲜艳的背景和特殊效果,以及模拟光影。(answers.com)
线性渐变
线性渐变是沿着一条直线进行的颜色或色调的混合。它们是通过 cairo_pattern_create_linear 函数创建的。
#include <cairo.h>
#include <gtk/gtk.h>
void draw_gradient1(cairo_t *);
void draw_gradient2(cairo_t *);
void draw_gradient3(cairo_t *);
static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr,
gpointer user_data)
{
draw_gradient1(cr);
draw_gradient2(cr);
draw_gradient3(cr);
return FALSE;
}
void draw_gradient1(cairo_t *cr)
{
cairo_pattern_t *pat1;
pat1 = cairo_pattern_create_linear(0.0, 0.0, 350.0, 350.0);
gdouble j;
gint count = 1;
for ( j = 0.1; j < 1; j += 0.1 ) {
if (( count % 2 )) {
cairo_pattern_add_color_stop_rgb(pat1, j, 0, 0, 0);
} else {
cairo_pattern_add_color_stop_rgb(pat1, j, 1, 0, 0);
}
count++;
}
cairo_rectangle(cr, 20, 20, 300, 100);
cairo_set_source(cr, pat1);
cairo_fill(cr);
cairo_pattern_destroy(pat1);
}
void draw_gradient2(cairo_t *cr)
{
cairo_pattern_t *pat2;
pat2 = cairo_pattern_create_linear(0.0, 0.0, 350.0, 0.0);
gdouble i;
gint count = 1;
for ( i = 0.05; i < 0.95; i += 0.025 ) {
if (( count % 2 )) {
cairo_pattern_add_color_stop_rgb(pat2, i, 0, 0, 0);
} else {
cairo_pattern_add_color_stop_rgb(pat2, i, 0, 0, 1);
}
count++;
}
cairo_rectangle(cr, 20, 140, 300, 100);
cairo_set_source(cr, pat2);
cairo_fill(cr);
cairo_pattern_destroy(pat2);
}
void draw_gradient3(cairo_t *cr)
{
cairo_pattern_t *pat3;
pat3 = cairo_pattern_create_linear(20.0, 260.0, 20.0, 360.0);
cairo_pattern_add_color_stop_rgb(pat3, 0.1, 0, 0, 0);
cairo_pattern_add_color_stop_rgb(pat3, 0.5, 1, 1, 0);
cairo_pattern_add_color_stop_rgb(pat3, 0.9, 0, 0, 0);
cairo_rectangle(cr, 20, 260, 300, 100);
cairo_set_source(cr, pat3);
cairo_fill(cr);
cairo_pattern_destroy(pat3);
}
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *darea;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
darea = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER (window), darea);
g_signal_connect(G_OBJECT(darea), "draw",
G_CALLBACK(on_draw_event), NULL);
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 340, 390);
gtk_window_set_title(GTK_WINDOW(window), "Linear gradients");
gtk_widget_set_app_paintable(window, TRUE);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
该示例绘制了三个用线性渐变填充的矩形。
pat3 = cairo_pattern_create_linear(20.0, 260.0, 20.0, 360.0);
这里我们创建一个线性渐变图案。参数指定了绘制渐变的线。在我们的例子中,这是一条垂直线。
cairo_pattern_add_color_stop_rgb(pat3, 0.1, 0, 0, 0); cairo_pattern_add_color_stop_rgb(pat3, 0.5, 1, 1, 0); cairo_pattern_add_color_stop_rgb(pat3, 0.9, 0, 0, 0);
我们定义颜色停点来生成我们的渐变图案。在这种情况下,渐变是黑色和黄色颜色的混合。通过添加两个黑色和一种黄色停点,我们创建了一个水平渐变图案。这些停点实际是什么意思?在我们的例子中,我们从黑色开始,它会在尺寸的 1/10 处停止。然后我们开始逐渐绘制黄色,这将在形状的中心达到顶峰。黄色在尺寸的 9/10 处停止,在那里我们再次开始绘制黑色,直到结束。
径向渐变
径向渐变是介于两个圆之间的颜色或色调的混合。cairo_pattern_create_radial 函数用于在 Cairo 中创建径向渐变。
#include <cairo.h>
#include <math.h>
#include <gtk/gtk.h>
void draw_gradient1(cairo_t *);
void draw_gradient2(cairo_t *);
static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr,
gpointer user_data)
{
draw_gradient1(cr);
draw_gradient2(cr);
return FALSE;
}
void draw_gradient1(cairo_t *cr)
{
cairo_pattern_t *r1;
cairo_set_source_rgba(cr, 0, 0, 0, 1);
cairo_set_line_width(cr, 12);
cairo_translate(cr, 60, 60);
r1 = cairo_pattern_create_radial(30, 30, 10, 30, 30, 90);
cairo_pattern_add_color_stop_rgba(r1, 0, 1, 1, 1, 1);
cairo_pattern_add_color_stop_rgba(r1, 1, 0.6, 0.6, 0.6, 1);
cairo_set_source(cr, r1);
cairo_arc(cr, 0, 0, 40, 0, M_PI * 2);
cairo_fill(cr);
cairo_pattern_destroy(r1);
}
void draw_gradient2(cairo_t *cr)
{
cairo_pattern_t *r2;
cairo_translate(cr, 120, 0);
r2 = cairo_pattern_create_radial(0, 0, 10, 0, 0, 40);
cairo_pattern_add_color_stop_rgb(r2, 0, 1, 1, 0);
cairo_pattern_add_color_stop_rgb(r2, 0.8, 0, 0, 0);
cairo_set_source(cr, r2);
cairo_arc(cr, 0, 0, 40, 0, M_PI * 2);
cairo_fill(cr);
}
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *darea;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
darea = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER (window), darea);
g_signal_connect(G_OBJECT(darea), "draw",
G_CALLBACK(on_draw_event), NULL);
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
gtk_window_set_title(GTK_WINDOW(window), "Radial gradients");
gtk_widget_set_app_paintable(window, TRUE);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
在示例中,我们绘制了两个径向渐变。
r1 = cairo_pattern_create_radial(30, 30, 10, 30, 30, 90); cairo_pattern_add_color_stop_rgba(r1, 0, 1, 1, 1, 1); cairo_pattern_add_color_stop_rgba(r1, 1, 0.6, 0.6, 0.6, 1); cairo_set_source(cr, r1); cairo_arc(cr, 0, 0, 40, 0, M_PI * 2); cairo_fill(cr);
我们绘制了一个圆并用径向渐变填充其内部。径向渐变由两个圆定义。cairo_pattern_add_color_stop_rgba 函数定义了颜色。我们可以尝试更改圆的位置或半径的长度。在第一个渐变示例中,我们创建了一个看起来像 3D 形状的对象。
r2 = cairo_pattern_create_radial(0, 0, 10, 0, 0, 40); cairo_pattern_add_color_stop_rgb(r2, 0, 1, 1, 0); cairo_pattern_add_color_stop_rgb(r2, 0.8, 0, 0, 0); cairo_set_source(cr, r2); cairo_arc(cr, 0, 0, 40, 0, M_PI * 2); cairo_fill(cr);
在此示例中,定义径向渐变的圆和自定义绘制的圆具有共同的中心点。
在本章的 Cairo 图形教程中,我们涵盖了渐变。