PyCairo指南的这个部分,我们将讨论渐变。我们将提到线性的和径向的渐变。
在计算机图形学中,渐变是深浅的平滑的调配,由亮到暗,或者由一种颜色到另一种颜色。在2D制图程序和绘画程序中,渐变被用于创建五彩缤纷的背景和特殊的效果,也用于模拟灯光和阴影。
线性渐变是颜色的调配(两种不同的颜色)或颜色的深浅(一种颜色,R,G,B各色彩成分占比相同,但亮度不一样)变化都沿着一条直线。在PyCairo中,它们由一个 cairo.LinearGradient来表示。
#!/usr/bin/python ''' ZetCode PyCairo tutorial This program works with linear gradients in PyCairo author: Jan Bodnar website: zetcode.com last edited: August 2012 ''' import cairo import gtk class MainWindow(gtk.Window): def __init__(self): super(self.__class__, self).__init__() self.init_ui() def init_ui(self): darea = gtk.DrawingArea() darea.connect("expose_event", self.expose) self.add(darea) self.set_title("Linear gradients") self.resize(340, 390) self.set_position(gtk.WIN_POS_CENTER) self.connect("delete-event", gtk.main_quit) self.show_all() def expose(self, widget, event): self.context = widget.window.cairo_create() self.on_draw(300, self.context) def on_draw(self, wdith, cr): self.draw_gradient1(cr) self.draw_gradient2(cr) self.draw_gradient3(cr) def draw_gradient1(self, cr): lg1 = cairo.LinearGradient(0.0, 0.0, 350, 350) count = 1 i = 0.1 while i < 1.0: if count % 2: lg1.add_color_stop_rgba(i, 0, 0, 0, 1) else: lg1.add_color_stop_rgba(i, 1, 0, 0, 1) i = i + 0.1 count = count + 1 cr.rectangle(20, 20, 300, 100) cr.set_source(lg1) cr.fill() def draw_gradient2(self, cr): lg2 = cairo.LinearGradient(0.0, 0.0, 350, 0) count = 1 i = 0.05 while i < 0.95: if count % 2: lg2.add_color_stop_rgba(i, 0, 0, 0, 1) else: lg2.add_color_stop_rgba(i, 0, 0, 1, 1) i = i + 0.025 count = count + 1 cr.rectangle(20, 140, 300, 100) cr.set_source(lg2) cr.fill() def draw_gradient3(self, cr): lg3 = cairo.LinearGradient(20.0, 260.0, 20.0, 360.0) lg3.add_color_stop_rgba(0.1, 0, 0, 0, 1) lg3.add_color_stop_rgba(0.5, 1, 1, 0, 1) lg3.add_color_stop_rgba(0.9, 0, 0, 0, 1) cr.rectangle(20, 260, 300, 100) cr.set_source(lg3) cr.fill() def main(): window = MainWindow() gtk.main() if __name__ == "__main__": main()这个例子中,我们画了三个用线性渐变填充的矩形。
lg3 = cairo.LinearGradient(20.0, 260.0, 20.0, 360.0)此处我们创建了一个线性渐变。参数指定了一条直线,我们沿着这条直线画渐变效果。这是一条竖直直线。
lg3.add_color_stop_rgba(0.1, 0, 0, 0, 1) lg3.add_color_stop_rgba(0.5, 1, 1, 0, 1) lg3.add_color_stop_rgba(0.9, 0, 0, 0, 1)
我们定义了颜色中止点来产生我们的渐变模式。在这个例子中,渐变是黑色和黄色的调配。通过添加两个黑色的和一个黄色的中止点,我们创建了一个竖直的渐变模式。这些中止点实际意味着什么呢?在我们的例子中,我们以黑色开始,它会中止于1/10大小处。然后我们逐渐的用黄色来描绘,它会在形状的中心位置达到顶点。黄色终止于9/10大小处,我们也在此处开始再次用黑色描绘,直到终点。
Figure: Linear gradients
#!/usr/bin/python ''' ZetCode PyCairo tutorial This program works with radial gradients in PyCairo author: Jan Bodnar website: zetcode.com last edited: August 2012 ''' import cairo import gtk import math class MainWindow(gtk.Window): def __init__(self): super(self.__class__, self).__init__() self.init_ui() def init_ui(self): darea = gtk.DrawingArea() darea.connect("expose_event", self.expose) self.add(darea) self.set_title("Radial gradients") self.resize(300, 200) self.set_position(gtk.WIN_POS_CENTER) self.connect("delete-event", gtk.main_quit) self.show_all() def expose(self, widget, event): self.context = widget.window.cairo_create() self.on_draw(300, self.context) def on_draw(self, wdith, cr): self.draw_gradient1(cr) self.draw_gradient2(cr) def draw_gradient1(self, cr): cr.set_source_rgba(0, 0, 0, 1) cr.set_line_width(12) cr.translate(60, 60) r1 = cairo.RadialGradient(30, 30, 10, 30, 30, 90) r1.add_color_stop_rgba(0, 1, 1, 1, 1) r1.add_color_stop_rgba(1, 0.6, 0.6, 0.6, 1) cr.set_source(r1) cr.arc(0, 0, 40, 0, math.pi * 2) cr.fill() cr.translate(120, 0) def draw_gradient2(self, cr): r2 = cairo.RadialGradient(0, 0, 10, 0, 0, 40) r2.add_color_stop_rgb(0, 1, 1, 0) r2.add_color_stop_rgb(0.8, 0, 0, 0) cr.set_source(r2) cr.arc(0, 0, 40, 0, math.pi * 2) cr.fill() def main(): window = MainWindow() gtk.main() if __name__ == "__main__": main()这个例子中,我们画了两个径向渐变。
r1 = cairo.RadialGradient(30, 30, 10, 30, 30, 90) r1.add_color_stop_rgba(0, 1, 1, 1, 1) r1.add_color_stop_rgba(1, 0.6, 0.6, 0.6, 1) cr.set_source(r1) cr.arc(0, 0, 40, 0, math.pi * 2) cr.fill()
我们画了一个圆,并用一个径向渐变填充它的内部。径向渐变由两个圆来定义。add_color_stop_rgba()方法定义色彩。我们可以用不同的圆的位置和半径来做试验。在第一个渐变的例子中,我们创建了一个对象,它类似于一个3D形状。
r2 = cairo.RadialGradient(0, 0, 10, 0, 0, 40) r2.add_color_stop_rgb(0, 1, 1, 0) r2.add_color_stop_rgb(0.8, 0, 0, 0) cr.set_source(r2) cr.arc(0, 0, 40, 0, math.pi * 2) cr.fill()
在这个例子中,定义径向渐变的圆和将要绘制的圆,具有相同的中心位置。
Figure: Radial gradients
在这一章中,我们讨论了PyCairo的渐变。