Improve SVG support by allowing control of density/DPI

Switch pre-built libs from Imagemagick to Graphicsmagick
This commit is contained in:
Lovell Fuller 2016-02-01 18:21:03 +00:00
parent 56508e8d79
commit cf7664a854
15 changed files with 158 additions and 93 deletions

View File

@ -132,8 +132,8 @@
'<(module_root_dir)/lib/libglib-2.0.so', '<(module_root_dir)/lib/libglib-2.0.so',
'<(module_root_dir)/lib/libgobject-2.0.so', '<(module_root_dir)/lib/libgobject-2.0.so',
# Dependencies of dependencies, included for openSUSE support # Dependencies of dependencies, included for openSUSE support
'<(module_root_dir)/lib/libMagickCore-6.Q16.so', '<(module_root_dir)/lib/libGraphicsMagick.so',
'<(module_root_dir)/lib/libMagickWand-6.Q16.so', '<(module_root_dir)/lib/libGraphicsMagickWand.so',
'<(module_root_dir)/lib/libexif.so', '<(module_root_dir)/lib/libexif.so',
'<(module_root_dir)/lib/libgio-2.0.so', '<(module_root_dir)/lib/libgio-2.0.so',
'<(module_root_dir)/lib/libgmodule-2.0.so', '<(module_root_dir)/lib/libgmodule-2.0.so',

View File

@ -6,23 +6,27 @@ var sharp = require('sharp');
### Input ### Input
#### sharp([input]) #### sharp([input], [options])
Constructor to which further methods are chained. `input`, if present, can be one of: Constructor to which further methods are chained.
* Buffer containing JPEG, PNG, WebP, GIF* or TIFF image data, or `input`, if present, can be one of:
* Buffer containing JPEG, PNG, WebP, GIF, SVG or TIFF image data, or
* String containing the path to an image file, with most major formats supported. * String containing the path to an image file, with most major formats supported.
The object returned implements the JPEG, PNG, WebP, GIF, SVG or TIFF format image data
can be streamed into the object when `input` is `null` or `undefined`.
`options`, if present, is an Object with the following optional attributes:
* `density` an integral number representing the DPI for vector images, defaulting to 72.
The object returned by the constructor implements the
[stream.Duplex](http://nodejs.org/api/stream.html#stream_class_stream_duplex) class. [stream.Duplex](http://nodejs.org/api/stream.html#stream_class_stream_duplex) class.
JPEG, PNG, WebP, GIF* or TIFF format image data
can be streamed into the object when `input` is not provided.
JPEG, PNG or WebP format image data can be streamed out from this object. JPEG, PNG or WebP format image data can be streamed out from this object.
\* libvips 8.0.0+ is required for Buffer/Stream input of GIF and other `magick` formats.
```javascript ```javascript
sharp('input.jpg') sharp('input.jpg')
.resize(300, 200) .resize(300, 200)

View File

@ -2,11 +2,19 @@
### v0.13 - "*mind*" ### v0.13 - "*mind*"
#### v0.13.0 - TBD
* Improve vector image support by allowing control of density/DPI.
Switch pre-built libs from Imagemagick to Graphicsmagick.
[#110](https://github.com/lovell/sharp/issues/110)
[@bradisbell](https://github.com/bradisbell)
* Switch from libvips' C to C++ bindings, requires upgrade to v8.2.2. * Switch from libvips' C to C++ bindings, requires upgrade to v8.2.2.
[#299](https://github.com/lovell/sharp/issues/299) [#299](https://github.com/lovell/sharp/issues/299)
* Control number of open files in libvips' cache; breaks existing `cache` behaviour. * Control number of open files in libvips' cache; breaks existing `cache` behaviour.
[#315](https://github.com/lovell/sharp/issues/315) [#315](https://github.com/lovell/sharp/issues/315)
[@impomezia](https://github.com/impomezia)
* Ensure 16-bit input images can be embedded onto a transparent background. * Ensure 16-bit input images can be embedded onto a transparent background.
[#340](https://github.com/lovell/sharp/issues/340) [#340](https://github.com/lovell/sharp/issues/340)

View File

@ -15,7 +15,7 @@ npm install sharp
[![Linux Build Status](https://circleci.com/gh/lovell/sharp.svg?style=svg&circle-token=6cb6d1d287a51af83722b19ed8885377fbc85e5c)](https://circleci.com/gh/lovell/sharp) [![Linux Build Status](https://circleci.com/gh/lovell/sharp.svg?style=svg&circle-token=6cb6d1d287a51af83722b19ed8885377fbc85e5c)](https://circleci.com/gh/lovell/sharp)
libvips and its dependencies are fetched and stored within `node_modules/sharp` during `npm install`. libvips and its dependencies are fetched and stored within `node_modules/sharp` during `npm install`.
This involves an automated HTTPS download of approximately 7MB. This involves an automated HTTPS download of approximately 6MB.
Most recent Linux-based operating systems running on x64 and ARMv6+ CPUs should "just work", e.g.: Most recent Linux-based operating systems running on x64 and ARMv6+ CPUs should "just work", e.g.:

View File

@ -35,9 +35,9 @@ var maximum = {
}; };
// Constructor-factory // Constructor-factory
var Sharp = function(input) { var Sharp = function(input, options) {
if (!(this instanceof Sharp)) { if (!(this instanceof Sharp)) {
return new Sharp(input); return new Sharp(input, options);
} }
stream.Duplex.call(this); stream.Duplex.call(this);
this.options = { this.options = {
@ -46,6 +46,7 @@ var Sharp = function(input) {
streamIn: false, streamIn: false,
sequentialRead: false, sequentialRead: false,
limitInputPixels: maximum.pixels, limitInputPixels: maximum.pixels,
density: '72',
// ICC profiles // ICC profiles
iccProfilePath: path.join(__dirname, 'icc') + path.sep, iccProfilePath: path.join(__dirname, 'icc') + path.sep,
// resize options // resize options
@ -107,12 +108,13 @@ var Sharp = function(input) {
} else if (typeof input === 'object' && input instanceof Buffer) { } else if (typeof input === 'object' && input instanceof Buffer) {
// input=buffer // input=buffer
this.options.bufferIn = input; this.options.bufferIn = input;
} else if (typeof input === 'undefined') { } else if (typeof input === 'undefined' || input === null) {
// input=stream // input=stream
this.options.streamIn = true; this.options.streamIn = true;
} else { } else {
throw new Error('Unsupported input ' + typeof input); throw new Error('Unsupported input ' + typeof input);
} }
this._inputOptions(options);
return this; return this;
}; };
module.exports = Sharp; module.exports = Sharp;
@ -133,6 +135,27 @@ module.exports.format = sharp.format();
*/ */
module.exports.versions = versions; module.exports.versions = versions;
/*
Set input-related options
density: DPI at which to load vector images via libmagick
*/
Sharp.prototype._inputOptions = function(options) {
if (typeof options === 'object') {
if (typeof options.density !== 'undefined') {
if (
typeof options.density === 'number' && !Number.isNaN(options.density) &&
options.density % 1 === 0 && options.density > 0 && options.density <= 2400
) {
this.options.density = options.density.toString();
} else {
throw new Error('Invalid density (1 to 2400)' + options.density);
}
}
} else if (typeof options !== 'undefined' && options !== null) {
throw new Error('Invalid input options ' + options);
}
};
/* /*
Handle incoming chunk on Writable Stream Handle incoming chunk on Writable Stream
*/ */

View File

@ -19,16 +19,16 @@ export CXXFLAGS="-O3"
# Dependency version numbers # Dependency version numbers
VERSION_ZLIB=1.2.8 VERSION_ZLIB=1.2.8
VERSION_FFI=3.2.1 VERSION_FFI=3.2.1
VERSION_GLIB=2.46.2 VERSION_GLIB=2.47.5
VERSION_XML2=2.9.3 VERSION_XML2=2.9.3
VERSION_GSF=1.14.34 VERSION_GSF=1.14.34
VERSION_EXIF=0.6.21 VERSION_EXIF=0.6.21
VERSION_LCMS2=2.7
VERSION_GM=1.3.23
VERSION_JPEG=1.4.2 VERSION_JPEG=1.4.2
VERSION_PNG16=1.6.21 VERSION_PNG16=1.6.21
VERSION_LCMS2=2.7
VERSION_WEBP=0.5.0 VERSION_WEBP=0.5.0
VERSION_TIFF=4.0.6 VERSION_TIFF=4.0.6
VERSION_MAGICK=6.9.3-2
VERSION_ORC=0.4.24 VERSION_ORC=0.4.24
VERSION_VIPS=8.2.2 VERSION_VIPS=8.2.2
@ -44,9 +44,9 @@ cd ${DEPS}/ffi
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --disable-builddir && make install-strip ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --disable-builddir && make install-strip
mkdir ${DEPS}/glib mkdir ${DEPS}/glib
curl -Ls http://ftp.gnome.org/pub/gnome/sources/glib/2.46/glib-${VERSION_GLIB}.tar.xz | tar xJC ${DEPS}/glib --strip-components=1 curl -Ls https://download.gnome.org/sources/glib/2.47/glib-${VERSION_GLIB}.tar.xz | tar xJC ${DEPS}/glib --strip-components=1
cd ${DEPS}/glib cd ${DEPS}/glib
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --with-pcre=internal && make install-strip
mkdir ${DEPS}/xml2 mkdir ${DEPS}/xml2
curl -Ls http://xmlsoft.org/sources/libxml2-${VERSION_XML2}.tar.gz | tar xzC ${DEPS}/xml2 --strip-components=1 curl -Ls http://xmlsoft.org/sources/libxml2-${VERSION_XML2}.tar.gz | tar xzC ${DEPS}/xml2 --strip-components=1
@ -54,7 +54,7 @@ cd ${DEPS}/xml2
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --without-python --with-zlib=${TARGET} && make install-strip ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --without-python --with-zlib=${TARGET} && make install-strip
mkdir ${DEPS}/gsf mkdir ${DEPS}/gsf
curl -Ls http://ftp.gnome.org/pub/GNOME/sources/libgsf/1.14/libgsf-${VERSION_GSF}.tar.xz | tar xJC ${DEPS}/gsf --strip-components=1 curl -Ls https://download.gnome.org/sources/libgsf/1.14/libgsf-${VERSION_GSF}.tar.xz | tar xJC ${DEPS}/gsf --strip-components=1
cd ${DEPS}/gsf cd ${DEPS}/gsf
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
@ -63,6 +63,16 @@ curl -Ls http://heanet.dl.sourceforge.net/project/libexif/libexif/${VERSION_EXIF
cd ${DEPS}/exif cd ${DEPS}/exif
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
mkdir ${DEPS}/lcms2
curl -Ls http://heanet.dl.sourceforge.net/project/lcms/lcms/${VERSION_LCMS2}/lcms2-${VERSION_LCMS2}.tar.gz | tar xzC ${DEPS}/lcms2 --strip-components=1
cd ${DEPS}/lcms2
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
mkdir ${DEPS}/gm
curl -Ls http://heanet.dl.sourceforge.net/project/graphicsmagick/graphicsmagick/${VERSION_GM}/GraphicsMagick-${VERSION_GM}.tar.xz | tar xJC ${DEPS}/gm --strip-components=1
cd ${DEPS}/gm
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --without-magick-plus-plus && make install-strip
mkdir ${DEPS}/jpeg mkdir ${DEPS}/jpeg
curl -Ls http://heanet.dl.sourceforge.net/project/libjpeg-turbo/${VERSION_JPEG}/libjpeg-turbo-${VERSION_JPEG}.tar.gz | tar xzC ${DEPS}/jpeg --strip-components=1 curl -Ls http://heanet.dl.sourceforge.net/project/libjpeg-turbo/${VERSION_JPEG}/libjpeg-turbo-${VERSION_JPEG}.tar.gz | tar xzC ${DEPS}/jpeg --strip-components=1
cd ${DEPS}/jpeg cd ${DEPS}/jpeg
@ -73,27 +83,17 @@ curl -Ls http://heanet.dl.sourceforge.net/project/libpng/libpng16/${VERSION_PNG1
cd ${DEPS}/png16 cd ${DEPS}/png16
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
mkdir ${DEPS}/lcms2
curl -Ls http://heanet.dl.sourceforge.net/project/lcms/lcms/${VERSION_LCMS2}/lcms2-${VERSION_LCMS2}.tar.gz | tar xzC ${DEPS}/lcms2 --strip-components=1
cd ${DEPS}/lcms2
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
mkdir ${DEPS}/webp mkdir ${DEPS}/webp
curl -Ls http://downloads.webmproject.org/releases/webp/libwebp-${VERSION_WEBP}.tar.gz | tar xzC ${DEPS}/webp --strip-components=1 curl -Ls http://downloads.webmproject.org/releases/webp/libwebp-${VERSION_WEBP}.tar.gz | tar xzC ${DEPS}/webp --strip-components=1
cd ${DEPS}/webp cd ${DEPS}/webp
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
mkdir ${DEPS}/tiff mkdir ${DEPS}/tiff
curl -Ls http://download.osgeo.org/libtiff/tiff-${VERSION_TIFF}.tar.gz /deps/tiff.tar.gz | tar xzC ${DEPS}/tiff --strip-components=1 curl -Ls http://download.osgeo.org/libtiff/tiff-${VERSION_TIFF}.tar.gz | tar xzC ${DEPS}/tiff --strip-components=1
cd ${DEPS}/tiff cd ${DEPS}/tiff
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
rm ${TARGET}/lib/libtiffxx* rm ${TARGET}/lib/libtiffxx*
mkdir ${DEPS}/magick
curl -Ls http://www.imagemagick.org/download/releases/ImageMagick-${VERSION_MAGICK}.tar.xz | tar xJC ${DEPS}/magick --strip-components=1
cd ${DEPS}/magick
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --without-magick-plus-plus && make install-strip
mkdir ${DEPS}/orc mkdir ${DEPS}/orc
curl -Ls http://gstreamer.freedesktop.org/data/src/orc/orc-${VERSION_ORC}.tar.xz | tar xJC ${DEPS}/orc --strip-components=1 curl -Ls http://gstreamer.freedesktop.org/data/src/orc/orc-${VERSION_ORC}.tar.xz | tar xJC ${DEPS}/orc --strip-components=1
cd ${DEPS}/orc cd ${DEPS}/orc
@ -103,7 +103,7 @@ mkdir ${DEPS}/vips
curl -Ls http://www.vips.ecs.soton.ac.uk/supported/8.2/vips-${VERSION_VIPS}.tar.gz | tar xzC ${DEPS}/vips --strip-components=1 curl -Ls http://www.vips.ecs.soton.ac.uk/supported/8.2/vips-${VERSION_VIPS}.tar.gz | tar xzC ${DEPS}/vips --strip-components=1
cd ${DEPS}/vips cd ${DEPS}/vips
./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking \ ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking \
--disable-debug --disable-introspection --without-python --without-fftw \ --disable-debug --disable-introspection --without-python --without-fftw --with-magickpackage=GraphicsMagick \
--with-zip-includes=${TARGET}/include --with-zip-libraries=${TARGET}/lib \ --with-zip-includes=${TARGET}/include --with-zip-libraries=${TARGET}/lib \
--with-jpeg-includes=${TARGET}/include --with-jpeg-libraries=${TARGET}/lib \ --with-jpeg-includes=${TARGET}/include --with-jpeg-libraries=${TARGET}/lib \
&& make install-strip && make install-strip
@ -117,20 +117,20 @@ rm -rf pkgconfig .libs *.la libvipsCC*
# Create JSON file of version numbers # Create JSON file of version numbers
cd ${TARGET} cd ${TARGET}
echo "{\n\ echo "{\n\
\"zlib\": \"${VERSION_ZLIB}\",\n\ \"exif\": \"${VERSION_EXIF}\",\n\
\"ffi\": \"${VERSION_FFI}\",\n\ \"ffi\": \"${VERSION_FFI}\",\n\
\"glib\": \"${VERSION_GLIB}\",\n\ \"glib\": \"${VERSION_GLIB}\",\n\
\"xml\": \"${VERSION_XML2}\",\n\
\"gsf\": \"${VERSION_GSF}\",\n\ \"gsf\": \"${VERSION_GSF}\",\n\
\"exif\": \"${VERSION_EXIF}\",\n\
\"jpeg\": \"${VERSION_JPEG}\",\n\ \"jpeg\": \"${VERSION_JPEG}\",\n\
\"png\": \"${VERSION_PNG16}\",\n\
\"lcms\": \"${VERSION_LCMS2}\",\n\ \"lcms\": \"${VERSION_LCMS2}\",\n\
\"webp\": \"${VERSION_WEBP}\",\n\ \"gm\": \"${VERSION_GM}\",\n\
\"tiff\": \"${VERSION_TIFF}\",\n\
\"magick\": \"${VERSION_MAGICK}\",\n\
\"orc\": \"${VERSION_ORC}\",\n\ \"orc\": \"${VERSION_ORC}\",\n\
\"png\": \"${VERSION_PNG16}\",\n\
\"tiff\": \"${VERSION_TIFF}\",\n\
\"vips\": \"${VERSION_VIPS}\"\n\ \"vips\": \"${VERSION_VIPS}\"\n\
\"webp\": \"${VERSION_WEBP}\",\n\
\"xml\": \"${VERSION_XML2}\",\n\
\"zlib\": \"${VERSION_ZLIB}\",\n\
}" >lib/versions.json }" >lib/versions.json
# Create .tar.gz # Create .tar.gz

View File

@ -20,16 +20,16 @@ ENV PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:${TARGET}/lib/pkgconfig \
# Dependency version numbers # Dependency version numbers
ENV VERSION_ZLIB=1.2.8 \ ENV VERSION_ZLIB=1.2.8 \
VERSION_FFI=3.2.1 \ VERSION_FFI=3.2.1 \
VERSION_GLIB=2.46.2 \ VERSION_GLIB=2.47.5 \
VERSION_XML2=2.9.3 \ VERSION_XML2=2.9.3 \
VERSION_GSF=1.14.34 \ VERSION_GSF=1.14.34 \
VERSION_EXIF=0.6.21 \ VERSION_EXIF=0.6.21 \
VERSION_LCMS2=2.7 \
VERSION_GM=1.3.23 \
VERSION_JPEG=1.4.2 \ VERSION_JPEG=1.4.2 \
VERSION_PNG16=1.6.21 \ VERSION_PNG16=1.6.21 \
VERSION_LCMS2=2.7 \
VERSION_WEBP=0.5.0 \ VERSION_WEBP=0.5.0 \
VERSION_TIFF=4.0.6 \ VERSION_TIFF=4.0.6 \
VERSION_MAGICK=6.9.3-2 \
VERSION_ORC=0.4.24 \ VERSION_ORC=0.4.24 \
VERSION_VIPS=8.2.2 VERSION_VIPS=8.2.2
@ -45,9 +45,9 @@ WORKDIR ${DEPS}/ffi
RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --disable-builddir && make install-strip RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --disable-builddir && make install-strip
RUN mkdir ${DEPS}/glib RUN mkdir ${DEPS}/glib
RUN curl -Ls http://ftp.gnome.org/pub/gnome/sources/glib/2.46/glib-${VERSION_GLIB}.tar.xz | tar xJC ${DEPS}/glib --strip-components=1 RUN curl -Ls https://download.gnome.org/sources/glib/2.47/glib-${VERSION_GLIB}.tar.xz | tar xJC ${DEPS}/glib --strip-components=1
WORKDIR ${DEPS}/glib WORKDIR ${DEPS}/glib
RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --with-pcre=internal && make install-strip
RUN mkdir ${DEPS}/xml2 RUN mkdir ${DEPS}/xml2
RUN curl -Ls http://xmlsoft.org/sources/libxml2-${VERSION_XML2}.tar.gz | tar xzC ${DEPS}/xml2 --strip-components=1 RUN curl -Ls http://xmlsoft.org/sources/libxml2-${VERSION_XML2}.tar.gz | tar xzC ${DEPS}/xml2 --strip-components=1
@ -55,7 +55,7 @@ WORKDIR ${DEPS}/xml2
RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --without-python --with-zlib=${TARGET} && make install-strip RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --without-python --with-zlib=${TARGET} && make install-strip
RUN mkdir ${DEPS}/gsf RUN mkdir ${DEPS}/gsf
RUN curl -Ls http://ftp.gnome.org/pub/GNOME/sources/libgsf/1.14/libgsf-${VERSION_GSF}.tar.xz | tar xJC ${DEPS}/gsf --strip-components=1 RUN curl -Ls https://download.gnome.org/sources/libgsf/1.14/libgsf-${VERSION_GSF}.tar.xz | tar xJC ${DEPS}/gsf --strip-components=1
WORKDIR ${DEPS}/gsf WORKDIR ${DEPS}/gsf
RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
@ -64,6 +64,16 @@ RUN curl -Ls http://heanet.dl.sourceforge.net/project/libexif/libexif/${VERSION_
WORKDIR ${DEPS}/exif WORKDIR ${DEPS}/exif
RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
RUN mkdir ${DEPS}/lcms2
RUN curl -Ls http://heanet.dl.sourceforge.net/project/lcms/lcms/${VERSION_LCMS2}/lcms2-${VERSION_LCMS2}.tar.gz | tar xzC ${DEPS}/lcms2 --strip-components=1
WORKDIR ${DEPS}/lcms2
RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
RUN mkdir ${DEPS}/gm
RUN curl -Ls http://heanet.dl.sourceforge.net/project/graphicsmagick/graphicsmagick/${VERSION_GM}/GraphicsMagick-${VERSION_GM}.tar.xz | tar xJC ${DEPS}/gm --strip-components=1
WORKDIR ${DEPS}/gm
RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --without-magick-plus-plus && make install-strip
RUN mkdir ${DEPS}/jpeg RUN mkdir ${DEPS}/jpeg
RUN curl -Ls http://heanet.dl.sourceforge.net/project/libjpeg-turbo/${VERSION_JPEG}/libjpeg-turbo-${VERSION_JPEG}.tar.gz | tar xzC ${DEPS}/jpeg --strip-components=1 RUN curl -Ls http://heanet.dl.sourceforge.net/project/libjpeg-turbo/${VERSION_JPEG}/libjpeg-turbo-${VERSION_JPEG}.tar.gz | tar xzC ${DEPS}/jpeg --strip-components=1
WORKDIR ${DEPS}/jpeg WORKDIR ${DEPS}/jpeg
@ -74,27 +84,17 @@ RUN curl -Ls http://heanet.dl.sourceforge.net/project/libpng/libpng16/${VERSION_
WORKDIR ${DEPS}/png16 WORKDIR ${DEPS}/png16
RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
RUN mkdir ${DEPS}/lcms2
RUN curl -Ls http://heanet.dl.sourceforge.net/project/lcms/lcms/${VERSION_LCMS2}/lcms2-${VERSION_LCMS2}.tar.gz | tar xzC ${DEPS}/lcms2 --strip-components=1
WORKDIR ${DEPS}/lcms2
RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
RUN mkdir ${DEPS}/webp RUN mkdir ${DEPS}/webp
RUN curl -Ls http://downloads.webmproject.org/releases/webp/libwebp-${VERSION_WEBP}.tar.gz | tar xzC ${DEPS}/webp --strip-components=1 RUN curl -Ls http://downloads.webmproject.org/releases/webp/libwebp-${VERSION_WEBP}.tar.gz | tar xzC ${DEPS}/webp --strip-components=1
WORKDIR ${DEPS}/webp WORKDIR ${DEPS}/webp
RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
RUN mkdir ${DEPS}/tiff RUN mkdir ${DEPS}/tiff
RUN curl -Ls http://download.osgeo.org/libtiff/tiff-${VERSION_TIFF}.tar.gz /deps/tiff.tar.gz | tar xzC ${DEPS}/tiff --strip-components=1 RUN curl -Ls http://download.osgeo.org/libtiff/tiff-${VERSION_TIFF}.tar.gz | tar xzC ${DEPS}/tiff --strip-components=1
WORKDIR ${DEPS}/tiff WORKDIR ${DEPS}/tiff
RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip
RUN rm ${TARGET}/lib/libtiffxx* RUN rm ${TARGET}/lib/libtiffxx*
RUN mkdir ${DEPS}/magick
RUN curl -Ls http://www.imagemagick.org/download/releases/ImageMagick-${VERSION_MAGICK}.tar.xz | tar xJC ${DEPS}/magick --strip-components=1
WORKDIR ${DEPS}/magick
RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --without-magick-plus-plus && make install-strip
RUN mkdir ${DEPS}/orc RUN mkdir ${DEPS}/orc
RUN curl -Ls http://gstreamer.freedesktop.org/data/src/orc/orc-${VERSION_ORC}.tar.xz | tar xJC ${DEPS}/orc --strip-components=1 RUN curl -Ls http://gstreamer.freedesktop.org/data/src/orc/orc-${VERSION_ORC}.tar.xz | tar xJC ${DEPS}/orc --strip-components=1
WORKDIR ${DEPS}/orc WORKDIR ${DEPS}/orc
@ -104,7 +104,7 @@ RUN mkdir ${DEPS}/vips
RUN curl -Ls http://www.vips.ecs.soton.ac.uk/supported/8.2/vips-${VERSION_VIPS}.tar.gz | tar xzC ${DEPS}/vips --strip-components=1 RUN curl -Ls http://www.vips.ecs.soton.ac.uk/supported/8.2/vips-${VERSION_VIPS}.tar.gz | tar xzC ${DEPS}/vips --strip-components=1
WORKDIR ${DEPS}/vips WORKDIR ${DEPS}/vips
RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking \ RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking \
--disable-debug --disable-introspection --without-python --without-fftw \ --disable-debug --disable-introspection --without-python --without-fftw --with-magickpackage=GraphicsMagick \
--with-zip-includes=${TARGET}/include --with-zip-libraries=${TARGET}/lib \ --with-zip-includes=${TARGET}/include --with-zip-libraries=${TARGET}/lib \
--with-jpeg-includes=${TARGET}/include --with-jpeg-libraries=${TARGET}/lib \ --with-jpeg-includes=${TARGET}/include --with-jpeg-libraries=${TARGET}/lib \
&& make install-strip && make install-strip
@ -118,20 +118,20 @@ RUN rm -rf pkgconfig .libs *.la libvipsCC*
# Create JSON file of version numbers # Create JSON file of version numbers
WORKDIR ${TARGET} WORKDIR ${TARGET}
RUN echo "{\n\ RUN echo "{\n\
\"zlib\": \"${VERSION_ZLIB}\",\n\ \"exif\": \"${VERSION_EXIF}\",\n\
\"ffi\": \"${VERSION_FFI}\",\n\ \"ffi\": \"${VERSION_FFI}\",\n\
\"glib\": \"${VERSION_GLIB}\",\n\ \"glib\": \"${VERSION_GLIB}\",\n\
\"xml\": \"${VERSION_XML2}\",\n\
\"gsf\": \"${VERSION_GSF}\",\n\ \"gsf\": \"${VERSION_GSF}\",\n\
\"exif\": \"${VERSION_EXIF}\",\n\
\"jpeg\": \"${VERSION_JPEG}\",\n\ \"jpeg\": \"${VERSION_JPEG}\",\n\
\"png\": \"${VERSION_PNG16}\",\n\
\"lcms\": \"${VERSION_LCMS2}\",\n\ \"lcms\": \"${VERSION_LCMS2}\",\n\
\"webp\": \"${VERSION_WEBP}\",\n\ \"gm\": \"${VERSION_GM}\",\n\
\"tiff\": \"${VERSION_TIFF}\",\n\
\"magick\": \"${VERSION_MAGICK}\",\n\
\"orc\": \"${VERSION_ORC}\",\n\ \"orc\": \"${VERSION_ORC}\",\n\
\"png\": \"${VERSION_PNG16}\",\n\
\"tiff\": \"${VERSION_TIFF}\",\n\
\"vips\": \"${VERSION_VIPS}\"\n\ \"vips\": \"${VERSION_VIPS}\"\n\
\"webp\": \"${VERSION_WEBP}\",\n\
\"xml\": \"${VERSION_XML2}\",\n\
\"zlib\": \"${VERSION_ZLIB}\",\n\
}" >lib/versions.json }" >lib/versions.json
# Create .tar.gz # Create .tar.gz

View File

@ -77,6 +77,7 @@ struct PipelineBaton {
size_t bufferInLength; size_t bufferInLength;
std::string iccProfilePath; std::string iccProfilePath;
int limitInputPixels; int limitInputPixels;
std::string density;
std::string output; std::string output;
std::string outputFormat; std::string outputFormat;
void *bufferOut; void *bufferOut;
@ -129,6 +130,7 @@ struct PipelineBaton {
PipelineBaton(): PipelineBaton():
bufferInLength(0), bufferInLength(0),
limitInputPixels(0), limitInputPixels(0),
density(""),
outputFormat(""), outputFormat(""),
bufferOutLength(0), bufferOutLength(0),
topOffsetPre(-1), topOffsetPre(-1),
@ -201,8 +203,9 @@ class PipelineWorker : public AsyncWorker {
if (inputImageType != ImageType::UNKNOWN) { if (inputImageType != ImageType::UNKNOWN) {
try { try {
image = VImage::new_from_buffer( image = VImage::new_from_buffer(
baton->bufferIn, baton->bufferInLength, nullptr, baton->bufferIn, baton->bufferInLength, nullptr, VImage::option()
VImage::option()->set("access", baton->accessMethod) ->set("access", baton->accessMethod)
->set("density", baton->density.data())
); );
} catch (...) { } catch (...) {
(baton->err).append("Input buffer has corrupt header"); (baton->err).append("Input buffer has corrupt header");
@ -217,8 +220,9 @@ class PipelineWorker : public AsyncWorker {
if (inputImageType != ImageType::UNKNOWN) { if (inputImageType != ImageType::UNKNOWN) {
try { try {
image = VImage::new_from_file( image = VImage::new_from_file(
baton->fileIn.data(), baton->fileIn.data(), VImage::option()
VImage::option()->set("access", baton->accessMethod) ->set("access", baton->accessMethod)
->set("density", baton->density.data())
); );
} catch (...) { } catch (...) {
(baton->err).append("Input file has corrupt header"); (baton->err).append("Input file has corrupt header");
@ -997,6 +1001,8 @@ NAN_METHOD(pipeline) {
baton->iccProfilePath = attrAsStr(options, "iccProfilePath"); baton->iccProfilePath = attrAsStr(options, "iccProfilePath");
// Limit input images to a given number of pixels, where pixels = width * height // Limit input images to a given number of pixels, where pixels = width * height
baton->limitInputPixels = attrAs<int32_t>(options, "limitInputPixels"); baton->limitInputPixels = attrAs<int32_t>(options, "limitInputPixels");
// Density/DPI at which to load vector images via libmagick
baton->density = attrAsStr(options, "density");
// Extract image options // Extract image options
baton->topOffsetPre = attrAs<int32_t>(options, "topOffsetPre"); baton->topOffsetPre = attrAs<int32_t>(options, "topOffsetPre");
baton->leftOffsetPre = attrAs<int32_t>(options, "leftOffsetPre"); baton->leftOffsetPre = attrAs<int32_t>(options, "leftOffsetPre");

View File

@ -1,17 +0,0 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
id="Wikimedia logo"
viewBox="-599 -599 1198 1198" width="1024" height="1024">
<defs>
<clipPath id="mask">
<path d="M 47.5,-87.5 v 425 h -95 v -425 l -552,-552 v 1250 h 1199 v -1250 z" />
</clipPath>
</defs>
<g clip-path="url(#mask)">
<circle id="green parts" fill="#396" r="336.5"/>
<circle id="blue arc" fill="none" stroke="#069" r="480.25" stroke-width="135.5" />
</g>
<circle fill="#900" cy="-379.5" r="184.5" id="red circle"/>
</svg>

Before

Width:  |  Height:  |  Size: 692 B

3
test/fixtures/check.svg vendored Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path d="M30,76q6-14,13-26q6-12,14-23q8-12,13-17q3-4,6-6q1-1,5-2q8-1,12-1q1,0,1,1q0,1-1,2q-13,11-27,33q-14,21-24,44q-4,9-5,11q-1,2-9,2q-5,0-6-1q-1-1-5-6q-5-8-12-15q-3-4-3-6q0-2,4-5q3-2,6-2q3,0,8,3q5,4,10,14z" fill="green" />
</svg>

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

BIN
test/fixtures/expected/svg1200.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 B

BIN
test/fixtures/expected/svg72.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 938 B

View File

@ -84,7 +84,7 @@ module.exports = {
inputWebPWithTransparency: getPath('5_webp_a.webp'), // http://www.gstatic.com/webp/gallery3/5_webp_a.webp inputWebPWithTransparency: getPath('5_webp_a.webp'), // http://www.gstatic.com/webp/gallery3/5_webp_a.webp
inputTiff: getPath('G31D.TIF'), // http://www.fileformat.info/format/tiff/sample/e6c9a6e5253348f4aef6d17b534360ab/index.htm inputTiff: getPath('G31D.TIF'), // http://www.fileformat.info/format/tiff/sample/e6c9a6e5253348f4aef6d17b534360ab/index.htm
inputGif: getPath('Crash_test.gif'), // http://upload.wikimedia.org/wikipedia/commons/e/e3/Crash_test.gif inputGif: getPath('Crash_test.gif'), // http://upload.wikimedia.org/wikipedia/commons/e/e3/Crash_test.gif
inputSvg: getPath('Wikimedia-logo.svg'), // http://commons.wikimedia.org/wiki/File:Wikimedia-logo.svg inputSvg: getPath('check.svg'), // http://dev.w3.org/SVG/tools/svgweb/samples/svg-files/check.svg
inputPsd: getPath('free-gearhead-pack.psd'), // https://dribbble.com/shots/1624241-Free-Gearhead-Vector-Pack inputPsd: getPath('free-gearhead-pack.psd'), // https://dribbble.com/shots/1624241-Free-Gearhead-Vector-Pack
inputSvs: getPath('CMU-1-Small-Region.svs'), // http://openslide.cs.cmu.edu/download/openslide-testdata/Aperio/CMU-1-Small-Region.svs inputSvs: getPath('CMU-1-Small-Region.svs'), // http://openslide.cs.cmu.edu/download/openslide-testdata/Aperio/CMU-1-Small-Region.svs

View File

@ -634,20 +634,37 @@ describe('Input/output', function() {
}); });
if (sharp.format.magick.input.file) { if (sharp.format.magick.input.file) {
it('Convert SVG, if supported, to PNG', function(done) { it('Convert SVG to PNG at default 72DPI', function(done) {
sharp(fixtures.inputSvg) sharp(fixtures.inputSvg)
.resize(100, 100) .resize(1024)
.extract({left: 290, top: 760, width: 40, height: 40})
.toFormat('png') .toFormat('png')
.toBuffer(function(err, data, info) { .toBuffer(function(err, data, info) {
if (err) { if (err) {
assert.strictEqual(0, err.message.indexOf('Input file is missing or of an unsupported image format')); assert.strictEqual(0, err.message.indexOf('Input file is missing or of an unsupported image format'));
done(); done();
} else { } else {
assert.strictEqual(true, info.size > 0);
assert.strictEqual('png', info.format); assert.strictEqual('png', info.format);
assert.strictEqual(100, info.width); assert.strictEqual(40, info.width);
assert.strictEqual(100, info.height); assert.strictEqual(40, info.height);
fixtures.assertSimilar(fixtures.expected('svg.png'), data, done); fixtures.assertSimilar(fixtures.expected('svg72.png'), data, done);
}
});
});
it('Convert SVG to PNG at 300DPI', function(done) {
sharp(fixtures.inputSvg, { density: 1200 })
.resize(1024)
.extract({left: 290, top: 760, width: 40, height: 40})
.toFormat('png')
.toBuffer(function(err, data, info) {
if (err) {
assert.strictEqual(0, err.message.indexOf('Input file is missing or of an unsupported image format'));
done();
} else {
assert.strictEqual('png', info.format);
assert.strictEqual(40, info.width);
assert.strictEqual(40, info.height);
fixtures.assertSimilar(fixtures.expected('svg1200.png'), data, done);
} }
}); });
}); });
@ -824,6 +841,27 @@ describe('Input/output', function() {
}); });
describe('Input options', function() {
it('Non-Object options fails', function() {
assert.throws(function() {
sharp(null, 'zoinks');
});
});
it('Invalid density: string', function() {
assert.throws(function() {
sharp(null, { density: 'zoinks' } );
});
});
it('Invalid density: float', function() {
assert.throws(function() {
sharp(null, { density: 0.5 } );
});
});
it('Ignore unknown attribute', function() {
sharp(null, { unknown: true } );
});
});
it('Queue length change events', function(done) { it('Queue length change events', function(done) {
var eventCounter = 0; var eventCounter = 0;
var queueListener = function(queueLength) { var queueListener = function(queueLength) {