[cairo] Writing Surface to PNG based on Window Context: POSSIBLE?

Neil Mayhew neil_mayhew at users.sourceforge.net
Fri Mar 20 18:22:11 PDT 2009


On 20/03/09 04:31 PM darethehair wrote:
> How does one invoke the 'write_to_png' in that situation? The reason I 
> ask this is that I would like to be able to draw on the 'screen', but 
> also re-direct to a PNG (or whatever) file if I want to.

You can't write a window to a PNG (not with cairo, anyway). However, you
can refactor your program into two parts: one that takes a cairo.Context
as a parameter and generates the desired graphics, and another one that
sets up the destination surface and context and calls the other
(drawing) part.

I've done this for one program I have been writing. It uses gtkmm and
cairomm rather than PyCairo, but the principle is the same. Depending on
the command-line arguments it either opens up a window and hooks the
pure-cairo drawing function to the expose event, or it creates a
pure-cairo surface, calls the drawing function on that, and then writes
it out. However, you could instead have a File -> Export menu item that
does the same thing.

In case it's helpful, I've included the code I am using. It's in C++,
but hopefully you can translate.

--Neil

void export(std::string filename, int size_x, int size_y)
{
    std::string suffix = filename.substr(filename.rfind('.') + 1);

    Cairo::RefPtr<Cairo::Surface> surface;

    if (suffix == "pdf")
        surface = Cairo::PdfSurface::create(filename, size_x, size_y);
    else if (suffix == "svg")
        surface = Cairo::SvgSurface::create(filename, size_x, size_y);
    else if (suffix == "ps")
        surface = Cairo::PsSurface::create(filename, size_x, size_y);
    else if (suffix == "png")
        surface = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, \
            size_x, size_y);
    else
        throw std::runtime_error("Unknown filename suffix");

    Cairo::RefPtr<Cairo::Context> context = \
	Cairo::Context::create(surface);

    if (suffix == "png")
    {
        context->set_source_rgb(1.0, 1.0, 1.0);
        context->paint();
    }

    render(context, size_x, size_y);

    if (suffix == "png")
        surface->write_to_png(filename);
}



More information about the cairo mailing list