Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve density/resolution of vector input images #110

Closed
lovell opened this issue Oct 24, 2014 · 23 comments
Closed

Improve density/resolution of vector input images #110

lovell opened this issue Oct 24, 2014 · 23 comments
Milestone

Comments

@lovell
Copy link
Owner

lovell commented Oct 24, 2014

(As originally suggested by @bradisbell in #105.)

libmagick is able to parse vector SVG files as bitmaps but the resolution is poor due to the default 72 (96?) DPI/density setting.

@lovell
Copy link
Owner Author

lovell commented Dec 5, 2014

I've added support for density to libvips via jcupitt/libvips@14c8aa3 and will revisit this once it's included in a 7.42.x release.

@jcupitt
Copy link
Contributor

jcupitt commented Jan 24, 2015

Hi, 7.42 is out now with this feature.

@lovell
Copy link
Owner Author

lovell commented Jan 25, 2015

Thanks John, I'll expose this feature after moving to libvips' new C++ bindings.

@lovell lovell added this to the v1.0.0 milestone Jan 31, 2015
@lovell lovell changed the title Add support for SVG input Improve density/resolution of SVG input images Nov 22, 2015
@lookfirst
Copy link

I think I totally need this, or at least something like this. I've got an Adobe Illustrator file that I'm converting to PNG. I need the ability to specify the density for the output PNG.

@lovell lovell changed the title Improve density/resolution of SVG input images Improve density/resolution of SVG/EPS input images Jan 15, 2016
@lookfirst
Copy link

@lovell To be clear, it is a .ai file, not .eps. =) Conversion is done with ghostscript+graphicsmagick

@lovell lovell changed the title Improve density/resolution of SVG/EPS input images Improve density/resolution of vector input images Jan 16, 2016
@lovell
Copy link
Owner Author

lovell commented Jan 16, 2016

@lookfirst Thanks, I've updated the title accordingly.

@lovell
Copy link
Owner Author

lovell commented Feb 2, 2016

Commit fdb27e1 on the mind branch (v0.13.0) adds much-improved support for vector images.

@lookfirst
Copy link

@lovell This looks really nice!

@jcupitt
Copy link
Contributor

jcupitt commented Feb 6, 2016

There's an interesting related issue here: https://github.com/jcupitt/libvips/issues/379

I'll have a stab at a libpoppler loader.

@jcupitt
Copy link
Contributor

jcupitt commented Feb 8, 2016

... jcupitt/libvips#379 has some benchmarks now, it's up to about 500x (!!???!?!) faster.

What features do you need in a vector graphics loader? Please feel free to add any ideas to the TODO on that issue.

@lovell
Copy link
Owner Author

lovell commented Feb 8, 2016

@jcupitt Wow, that's quite an improvement.

SVG is the vector format that has generated the most questions from sharp users. Given poppler's dependency on cairo, would support for loading via librsvg also make sense here?

@jcupitt
Copy link
Contributor

jcupitt commented Feb 8, 2016

Sure, I think that's a good idea. It should be a fairly simple copy-paste job to make pdfload.c into svgload.c. These dependencies are all optional so I have no problem adding more.

@jcupitt
Copy link
Contributor

jcupitt commented Feb 8, 2016

... I guess better GIF support is also asked for a lot. I don't know what the best gif library is.

@lovell
Copy link
Owner Author

lovell commented Feb 8, 2016

@jcupitt The public domain STB library provides a common API for decoding GIF, PSD and a few others at https://github.com/nothings/stb/blob/master/stb_image.h

@jcupitt
Copy link
Contributor

jcupitt commented Feb 8, 2016

I don't like the STB stuff, it seems broken by design to me. It makes my skin crawl!

I'll add a note about finding a gif library to the TODO.

@jcupitt
Copy link
Contributor

jcupitt commented Feb 9, 2016

I had a quick hack at a librsvg reader. This is a simple copy-paste from the new pdfload operator:

https://github.com/jcupitt/libvips/tree/add-librsvg

It's fast! I see:

$ time vipsthumbnail vips-profile.svg 
real    0m0.101s
user    0m0.092s
sys 0m0.012s

vs. git master, still using the libMagick pathway:

$ time vipsthumbnail vips-profile.svg 
real    0m0.207s
user    0m0.252s
sys 0m0.036s

It's not correctly loading from a memory buffer yet, I'm not sure why.

@jcupitt
Copy link
Contributor

jcupitt commented Feb 9, 2016

OK, fixed it, it seems to work well now.

I think the remaining issue is file type sniffing. At the moment it relies on files ending in .svg and buffers being valid SVG files (it just calls rsvg_handle_new_from_data() on the memory area).

Files not called .svg will be missed, and memory buffers will be very slow to detect, since it will (I think?) parse the whole buffer.

Do you know a good detect-svg rule? I guess first line starts <?xml, second line starts <svg, but that seems rather fragile. The code needs to go in here:

https://github.com/jcupitt/libvips/blob/add-librsvg/libvips/foreign/svgload.c#L366

@lovell
Copy link
Owner Author

lovell commented Feb 9, 2016

@jcupitt That's fast, and that's fast!

The <?xml ... declaration is optional in SVG (and in XML at large, although very much recommended). https://github.com/sindresorhus/is-svg/blob/master/index.js provides some hints, e.g. not binary, contains <svg and </svg>

@jcupitt
Copy link
Contributor

jcupitt commented Feb 9, 2016

Thanks @lovell, I've put something better in. I'll merge to master as soon as CMYK PDFs are sorted out.

@lovell
Copy link
Owner Author

lovell commented Feb 15, 2016

v0.13.0 now available, thanks everyone for the comments and help with this.

I'll create a separate issue to take advantage of libvips' new SVG and GIF loaders when v8.3.0 is available.

@lovell lovell closed this as completed Feb 15, 2016
@jcupitt
Copy link
Contributor

jcupitt commented Feb 18, 2016

One more related thing: the magickload in git master libvips now has a page parameter you can use to select the page to load of a multi-page document (or the gif frame to load of an animated gif). It gives a very nice speedup for things like PDF.

By default it always picks page zero, I don't know if sharp would need to expose this.

@lookfirst
Copy link

@lovell I'm playing with this and I'm a bit confused. I'm trying to read in a .ai file and output a .png file. I'd like the png to be output as 300dpi. Right now, I'm getting 25 dpi for the png file with sharp 0.13.0. Any ideas? Thanks!

    let transform = (width, height, density, toFormat) => {
        return sharp(null, {density: density})
            .resize(width, height)
            .max()
            .withoutEnlargement()
            .toFormat(toFormat);
    };

@lovell
Copy link
Owner Author

lovell commented Feb 22, 2016

@lookfirst density refers to *magick's rendering of a bitmap from a vector input.

In your example, this bitmap is then resized. Perhaps temporarily remove the resize operation to see more clearly what *magick is doing.

"I'd like the png to be output as 300dpi"

Once an image is in bitmap form, the DPI is mostly arbitrary - see #96 for why there are only "25" of them :)

Repository owner locked and limited conversation to collaborators Feb 22, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants