[cairo] [PATCH] Enable links to image files in SVG backend
Adrian Johnson
ajohnson at redneon.com
Fri Jan 1 01:36:50 PST 2010
Alexander Shulgin wrote:
> I'm scratching my personal itch here as I writing a simple Ruby
> program to generate nice calendars. I've used rcairo and pango and
> everything worked well except for putting photographic images into SVG
> files. Here comes inevitable rant... ;)
>
> 1. I have to convert[1] images from JPEG to PNG beforehand (a bit slow)
> 2. Then load them with rcairo (slow)
> 3. And render on SVG surface (even slower)
> 4. And then I get the output file of ridiculous 10-15 megs in size
> 5. Which can be finally loaded with Inkscape (really slow again) to
> fine-tune it.
The cairo 1.9.4 development snapshot contains new API for embedding JPEG
data in backends that support it (currently SVG, PDF, PS, and
Win32-printing).
The cairo_surface_set_mime_data() function associates JPEG data (and
other formats) with a surface. When a surface with mime data is used as
a source in a backend that supports the mime data, the mime data will be
embedded instead of the image data.
> [1] Again, I'm doing my stuff in Ruby, and I found no way to obtain
> necessary image data from JPEG file to feed to
> cairo_image_surface_create_for_data(). Using gdk-pixbuf is of no help
> as it gives BGR instead of RGB expected by cairo (or vice-versa).
If you are only using a backend that supports JPEG embedding and you
know that no fallback images containing any part of your image will be
used you can get away with using uninitialized image data as only the
mime data will be used.
> I'd also would like to see something like
> cairo_placeholder_surface_create(width, height) which will create a
> surface with no image data associated--I don't need it to render to
> SVG with links to file. Currently I'm forced to use
> cairo_image_surface_create() which still allocates height*stride
> bytes. No problem for a desktop, but can hurt some server's memory
> footprint.
If the image data will not be used, a solution to reduce the memory
usage would be to create a 1x1 image surface and set the JPEG mime data
on it. When painting the surface, you would need to scale the 1x1 image
with size of the JPEG image to get the correct size output.
eg
image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1);
cairo_surface_set_mime_data (image, CAIRO_MIME_TYPE_JPEG,
data, len, free, data);
cairo_scale (cr, jpeg_width, jpeg_height);
cairo_set_source_surface (cr, image, 0, 0);
cairo_paint (cr);
However testing this with the PDF, PS, and SVG backends shows that none
of them work. They only work if the image size is the same size as the
JPEG image. But that should not be hard to fix.
More information about the cairo
mailing list