CairoSVG icon indicating copy to clipboard operation
CairoSVG copied to clipboard

Expose method to get ARGB buffer or Cairo.ImageSurface

Open M0M097 opened this issue 10 months ago • 6 comments

It would be super nice to have an easy and portable way to rasterize an SVG string directly into a ARGB/RGBA buffer. While I have to admit that I did not check the source, I assume that internally CairoSVG first creates an ARGB buffer and/or Cairo.ImageSurface which is then encoded into png.

Would it be possible to directly expose the method that creates the raw ARGB buffer or Cairo.ImageSurface?

The only other option at the moment seems to be to use librsvg and pycairo directly. While this works fine on desktop, I failed to bundle librsvg for android. CairoSVG on the other hand works perfectly fine and is super portable.

Thanks :)

M0M097 avatar Feb 04 '25 12:02 M0M097

Hi!

While I have to admit that I did not check the source, I assume that internally CairoSVG first creates an ARGB buffer and/or Cairo.ImageSurface which is then encoded into png.

Then you should take a minute to look at it. 😄

PNGSurface has a cairo attribute that’s an ImageSurface.

liZe avatar Feb 04 '25 12:02 liZe

Thanks, so I would use it like this?

def svg_to_cairo_ImageSurface(svg_data, width, height, scale):
    return surface.PNGSurface.convert(
        bytestring=svg_data,
        write_to=None,   # This should prevent creation of a PNG file/bytes
        output_width=width,
        output_height=height,
        scale=scale
    ).cairo

Maybe this could be wrapped into a higher level routine?

M0M097 avatar Feb 04 '25 13:02 M0M097

Maybe this could be wrapped into a higher level routine?

That’s literally 1 line of code, a wrapper would be a bit over-engineered in my opinion. 😄

liZe avatar Feb 04 '25 13:02 liZe

In a sense yes, but one has to actually look at the source code to come up with this. As a normal user it would be nicer, if there would just be a svg2rgba or svg2cairo_ImageSurface function and the documentation would point to it. At least for svg2rgba also a few more lines of code would be needed ;)

M0M097 avatar Feb 04 '25 13:02 M0M097

My previous snippet did indeed not work. What seems to work is this:

from cairosvg.parser import Tree
from cairosvg.surface import PNGSurface

def svg2cairo_ImageSurface(svg_data, width, height, scale=1.0):
    tree = Tree(bytestring=svg_data)

    png_surface = PNGSurface(
        tree,
        output=None,        # No file or bytes—just render into memory
        dpi=96,
        parent_width=None,
        parent_height=None,
        scale=scale,
        output_width=width,
        output_height=height,
        background_color=None,
        map_rgba=None,
        map_image=None,
    )

    # Is this step necessary?
    png_surface.finish()

    return png_surface.cairo

As said, figuring this is out is not fully trivial in my opinion.

M0M097 avatar Feb 04 '25 16:02 M0M097

As said, figuring this is out is not fully trivial in my opinion.

No, you’re right it’s not. We should write a real Python API documentation.

liZe avatar Feb 04 '25 16:02 liZe