En esta receta, crearemos una figura, o un Surface usando la nomenclatura de Cairo, a partir de una imagen en formato SVG.

Ingredientes

  • python
  • python-cairo

Son paquetes muy comunes, así que es muy posible que ya los tengas instalados.

Lo primero de todo: El esqueleto GTK

Este código es muy simple. Si no has trabajado nunca con GTK, por favor, echa un vistazo a alguno de los manuales que hay por Internet…

El objetivo es tener un “Context” de Cairo, el objeto principal para dibujar cosas en Cairo. Es fácil, tenemos un método muy útil en gtk.gdk.window que hace el trabajo por nosotros: cairo_create(). La ventana que vamos a usar está dentro de un DrawingArea, así que:

#!/usr/bin/env python
# -*- mode: python; coding: utf-8 -*-

import gtk
import cairo

class Test:
    def __init__(self):
        mw = gtk.Window(gtk.WINDOW_TOPLEVEL)
        mw.connect("delete-event", gtk.main_quit)
        mw.set_size_request(400, 400)

        da = gtk.DrawingArea()
        da.connect("expose_event", self.on_expose)
        mw.add(da)

        # Source image, loaded as a pixbuf
        self._img = gtk.gdk.pixbuf_new_from_file("photos.svg")

        mw.show_all()

if __name__ == "__main__":
    t = Test()
    try:
        gtk.main()
    except KeyboardInterrupt:
        gtk.main_quit()

Ok. Nothing new until here. I’ve loaded the SVG using a gtk.gdk.pixbuf because Cairo can use this as a source, so drawing it is simple. Moreover, I’ve connected the expose_event of the drawing area to a method of Test.

Now, drawing time

Take a look into the method on_expose():

    def on_expose(self, widget, event):
        cr = widget.window.cairo_create()

        # Normal image
        cr.set_source_pixbuf(self._img, 175, 50)
        cr.paint()

        # Black shape of same image
        cr.push_group()
        cr.set_source_pixbuf(self._img, 175, 150)
        cr.paint()
        src = cr.pop_group()
        cr.set_source_rgb(0, 0, 0)
        cr.mask(src)

        # Blue shape of same image, with alpha
        cr.set_source_pixbuf(self._img, 175, 250)
        cr.paint()

        cr.push_group()
        cr.set_source_pixbuf(self._img, 175, 250)
        cr.paint()
        src = cr.pop_group()
        cr.set_source_rgba(.5, .5, 1, .4)
        cr.mask(src)

As you can see, there are three drawn things. The first one is the SVG as is, using a plain paint() method. Easy. The result may be:

Of course, without the border and the shadows… :p The second item we see is more interesting. I’m going to use the alpha channel in the original SVG as a mask: where the image is transparent, nothing is drawn, so only the opaque pixels are used to paint. To achieve this, I’m using a feature of Cairo called groups. A group is like a layer where you can draw things. The difference is that this ‘layer’ can be used later as a pattern or as a surface.

This time, I’ll only paint in black, which gives this:

¡Voilá! As you can imagine, if you use other color, blue for example, and paint with alpha enabled, you could get something like a shinning effect, like this:

which is the third item in our example. :) And that’s all, folks!
Thanks for reading.

Código fuente

Referencias



blog comments powered by Disqus