Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

quickest way to get started with cairo

Tags:

cairo

I have taken passing shots at learning Cairo in the past, but always moved on in favor of some other graphics library. My problem is that I can't find a good tutorial that gives me a simple display for my surface. I have always ended up digging through GTK or QT documentation about things that have nothing to do with what I want to do. I want to learn Cairo, not a massive OO architecture.

What is a bare bones wrapper to give me a cross-platform window with a Cairo canvas to draw on?

like image 579
Eli Avatar asked Apr 07 '11 04:04

Eli


2 Answers

I have used cairo for virtually anything involving drawing. I work at a medical software company, so I prototype scientific data visualization and other things.

I have usually three ways to display my drawings:

  1. A GTK drawing area created with a Python script and GTK;
  2. A PNG image displayed directly on screen using Python Image Library show() method;
  3. A PNG image saved to disk, also via Python Image Library.

A simple script derived from cairographics examples, which actually I use as a template for any new project, is:

import gtk

class Canvas(gtk.DrawingArea):
    def __init__(self):
        super(Canvas, self).__init__()
        self.connect("expose_event", self.expose)
        self.set_size_request(800,500)

    def expose(self, widget, event):
        cr = widget.window.cairo_create()
        rect = self.get_allocation()

        # you can use w and h to calculate relative positions which
        # also change dynamically if window gets resized
        w = rect.width
        h = rect.height

        # here is the part where you actually draw
        cr.move_to(0,0)
        cr.line_to(w/2, h/2)
        cr.stroke()

window = gtk.Window()
canvas = Canvas()
window.add(canvas)
window.set_position(gtk.WIN_POS_CENTER)
window.show_all()
gtk.main()

Or if you prefer not to deal with GUI toolkits, you can create and display an image on screen, and optionally save it to file:

import cairo, Image

width = 800
height = 600

surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
cr = cairo.Context(surface)

# optional conversion from screen to cartesian coordinates:
cr.translate(0, height)
cr.scale(1, -1)

# something very similar to Japanese flag:
cr.set_source_rgb(1,1,1)
cr.rectangle(0, 0, width, height)
cr.fill()
cr.arc(width/2, height/2, 150, 0, 6.28)
cr.set_source_rgb(1,0,0)
cr.fill()

im = Image.frombuffer("RGBA",
                       (width, height),
                       surface.get_data(),
                       "raw",
                       "BGRA",
                       0,1) # don't ask me what these are!
im.show()
# im.save('filename', 'png')
like image 165
heltonbiker Avatar answered Sep 24 '22 03:09

heltonbiker


An answer to a related question demonstrates a very simple setup in Gtk2HS to draw on a drawingArea with Cairo.

import Graphics.UI.Gtk
import Graphics.Rendering.Cairo

main :: IO ()
main = do
    initGUI
    window      <- windowNew
    drawingArea <- drawingAreaNew
    containerAdd window drawingArea

    drawingArea `onExpose` (\_ -> renderScene drawingArea)
    window `onDestroy` mainQuit

    windowSetDefaultSize window 640 480
    widgetShowAll window
    mainGUI

renderScene :: DrawingArea -> IO Bool
renderScene da = do
    dw <- widgetGetDrawWindow da
    renderWithDrawable dw $ do setSourceRGBA 0.5 0.5 0.5 1.0
                               moveTo 100.0 100.0
                               showText "HelloWorld"

    return True

Simply pass your Cairo animation routine to renderWithDrawable dw in renderScene.

like image 31
Eli Avatar answered Sep 24 '22 03:09

Eli