diff --git a/.travis.yml b/.travis.yml index 3bb39f4..af2d4c4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,11 +4,10 @@ dist: trusty sudo: false go: - - "1.6" - - "1.7" - "1.8" - "1.9" - "1.10" + - "1.11" - "tip" env: @@ -18,6 +17,7 @@ env: - LIBVIPS=8.4.6 - LIBVIPS=8.5.8 - LIBVIPS=8.6.2 + - LIBVIPS=8.8.0 - LIBVIPS=master matrix: @@ -89,7 +89,7 @@ before_install: - vips --vips-version install: - - go get -u github.com/golang/lint/golint + - go get -u golang.org/x/lint/golint script: - diff -u <(echo -n) <(gofmt -s -d ./) diff --git a/README.md b/README.md index 4588758..55efe60 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ bimg was designed to be a small and efficient library supporting a common set of bimg is able to output images as JPEG, PNG and WEBP formats, including transparent conversion across them. -bimg uses internally libvips, a powerful library written in C for image processing which requires a [low memory footprint](http://www.vips.ecs.soton.ac.uk/index.php?title=Speed_and_Memory_Use) +bimg uses internally libvips, a powerful library written in C for image processing which requires a [low memory footprint](https://github.com/jcupitt/libvips/wiki/Speed_and_Memory_Use) and it's typically 4x faster than using the quickest ImageMagick and GraphicsMagick settings or Go native `image` package, and in some cases it's even 8x faster processing JPEG images. If you're looking for an HTTP based image processing solution, see [imaginary](https://github.com/h2non/imaginary). @@ -77,10 +77,10 @@ The [install script](https://github.com/h2non/bimg/blob/master/preinstall.sh) re ## Performance -libvips is probably the faster open source solution for image processing. +libvips is probably the fastest open source solution for image processing. Here you can see some performance test comparisons for multiple scenarios: -- [libvips speed and memory usage](http://www.vips.ecs.soton.ac.uk/index.php?title=Speed_and_Memory_Use) +- [libvips speed and memory usage](https://github.com/jcupitt/libvips/wiki/Speed-and-memory-use) ## Benchmark diff --git a/image.go b/image.go index 093d5a5..224dafa 100644 --- a/image.go +++ b/image.go @@ -203,7 +203,7 @@ func (i *Image) Metadata() (ImageMetadata, error) { } // Interpretation gets the image interpretation type. -// See: http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation +// See: https://jcupitt.github.io/libvips/API/current/VipsImage.html#VipsInterpretation func (i *Image) Interpretation() (Interpretation, error) { return ImageInterpretation(i.buffer) } diff --git a/metadata.go b/metadata.go index 77eac8c..f6562d6 100644 --- a/metadata.go +++ b/metadata.go @@ -43,7 +43,7 @@ func ColourspaceIsSupported(buf []byte) (bool, error) { } // ImageInterpretation returns the image interpretation type. -// See: http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation +// See: https://jcupitt.github.io/libvips/API/current/VipsImage.html#VipsInterpretation func ImageInterpretation(buf []byte) (Interpretation, error) { return vipsInterpretationBuffer(buf) } diff --git a/options.go b/options.go index 270a11c..706b506 100644 --- a/options.go +++ b/options.go @@ -89,7 +89,7 @@ const ( ) // Interpretation represents the image interpretation type. -// See: http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation +// See: https://jcupitt.github.io/libvips/API/current/VipsImage.html#VipsInterpretation type Interpretation int const ( @@ -119,7 +119,7 @@ const ( // Extend represents the image extend mode, used when the edges // of an image are extended, you can specify how you want the extension done. -// See: http://www.vips.ecs.soton.ac.uk/supported/8.4/doc/html/libvips/libvips-conversion.html#VIPS-EXTEND-BACKGROUND:CAPS +// See: https://jcupitt.github.io/libvips/API/current/libvips-conversion.html#VIPS-EXTEND-BACKGROUND:CAPS type Extend int const ( diff --git a/preinstall.sh b/preinstall.sh old mode 100644 new mode 100755 index 33d41fc..7547f23 --- a/preinstall.sh +++ b/preinstall.sh @@ -1,15 +1,15 @@ #!/bin/bash -vips_version_minimum=8.4.2 -vips_version_latest_major_minor=8.5 -vips_version_latest_patch=1 +vips_version_minimum=8.7.2 +vips_version_latest_major_minor=8.7 +vips_version_latest_patch=2 vips_version_full="$vips_version_latest_major_minor.$vips_version_latest_patch" openslide_version_minimum=3.4.0 openslide_version_latest_major_minor=3.4 openslide_version_latest_patch=1 -tarbal_url="https://github.com/jcupitt/libvips/releases/download/v$vips_version_full/vips-$vips_version_full.tar.gz" +tarbal_url="https://github.com/libvips/libvips/releases/download/v$vips_version_full/vips-$vips_version_full.tar.gz" install_libvips_from_source() { # Download tarball @@ -125,8 +125,8 @@ if [ $enable_openslide -eq 1 ] && [ -z $vips_with_openslide ] && [ $openslide_ex DISTRO=$(lsb_release -c -s) echo "Detected Debian Linux '$DISTRO'" case "$DISTRO" in - jessie|vivid|wily|xenial) - # Debian 8, Ubuntu 15 + jessie|vivid|wily|xenial|stretch) + # Debian 9, Debian 8, Ubuntu 15 echo "Installing libopenslide via apt-get" apt-get install -y libopenslide-dev ;; @@ -156,7 +156,7 @@ if [ $enable_openslide -eq 1 ] && [ -z $vips_with_openslide ] && [ $openslide_ex # RHEL/CentOS 7 echo "Installing libopenslide dependencies via yum" yum groupinstall -y "Development Tools" - yum install -y tar curl libpng-devel libjpeg-devel libxml2-devel zlib-devel openjpeg-devel libtiff-devel gdk-pixbuf2-devel sqlite-devel cairo-devel glib2-devel + yum install -y tar curl libpng-devel libjpeg-devel libxml2-devel zlib-devel openjpeg-devel libtiff-devel gdk-pixbuf2-devel sqlite-devel cairo-devel glib2-devel expat-devel install_libopenslide_from_source "--prefix=/usr" ;; "Red Hat Enterprise Linux release 6."*|"CentOS release 6."*|"Scientific Linux release 6."*) @@ -215,6 +215,12 @@ if [ -f /etc/debian_version ]; then apt-get install -y automake build-essential gobject-introspection gtk-doc-tools libglib2.0-dev libjpeg-dev libpng12-dev libwebp-dev libtiff5-dev libexif-dev libgsf-1-dev liblcms2-dev libxml2-dev swig libmagickcore-dev curl install_libvips_from_source ;; + stretch) + # Debian 9 + echo "Installing libvips dependencies via apt-get" + apt-get install -y automake build-essential gobject-introspection gtk-doc-tools libglib2.0-dev libjpeg-dev libpng-dev libwebp-dev libtiff5-dev libexif-dev libgsf-1-dev liblcms2-dev libxml2-dev swig libmagickcore-dev curl + install_libvips_from_source + ;; precise|wheezy|maya) # Debian 7, Ubuntu 12.04, Mint 13 echo "Installing libvips dependencies via apt-get" diff --git a/resizer.go b/resizer.go index b84b4d0..6cd97c7 100644 --- a/resizer.go +++ b/resizer.go @@ -12,6 +12,10 @@ import ( "math" ) +var ( + ErrExtractAreaParamsRequired = errors.New("extract area width/height params are required") +) + // resizer is used to transform a given image as byte buffer // with the passed options. func resizer(buf []byte, o Options) ([]byte, error) { @@ -274,7 +278,7 @@ func extractOrEmbedImage(image *C.VipsImage, o Options) (*C.VipsImage, error) { break case o.Top != 0 || o.Left != 0 || o.AreaWidth != 0 || o.AreaHeight != 0: if o.AreaWidth == 0 { - o.AreaHeight = o.Width + o.AreaWidth = o.Width } if o.AreaHeight == 0 { o.AreaHeight = o.Height @@ -444,7 +448,11 @@ func imageCalculations(o *Options, inWidth, inHeight int) float64 { switch { // Fixed width and height case o.Width > 0 && o.Height > 0: - factor = math.Min(xfactor, yfactor) + if o.Crop { + factor = math.Min(xfactor, yfactor) + } else { + factor = math.Max(xfactor, yfactor) + } // Fixed width, auto height case o.Width > 0: if o.Crop { diff --git a/resizer_test.go b/resizer_test.go index a4b54b0..6a116a2 100644 --- a/resizer_test.go +++ b/resizer_test.go @@ -364,6 +364,54 @@ func TestExtractCustomAxis(t *testing.T) { Write("testdata/test_extract_custom_axis_out.jpg", newImg) } +func TestExtractOrEmbedImage(t *testing.T) { + buf, _ := Read("testdata/test.jpg") + input, _, err := loadImage(buf) + if err != nil { + t.Fatalf("Unable to load image %s", err) + } + + o := Options{ + Top: 10, + Left: 10, + Width: 100, + Height: 200, + + // Fields to test + AreaHeight: 0, + AreaWidth: 0, + + Quality: 100, /* Needs a value to satisfy libvips */ + } + + result, err := extractOrEmbedImage(input, o) + if err != nil { + if err == ErrExtractAreaParamsRequired { + t.Fatalf("Expecting AreaWidth and AreaHeight to have been defined") + } + + t.Fatalf("Unknown error occurred %s", err) + } + + image, err := saveImage(result, o) + if err != nil { + t.Fatalf("Failed saving image %s", err) + } + + test, err := Size(image) + if err != nil { + t.Fatalf("Failed fetching the size %s", err) + } + + if test.Height != o.Height { + t.Errorf("Extract failed, resulting Height %d doesn't match %d", test.Height, o.Height) + } + + if test.Width != o.Width { + t.Errorf("Extract failed, resulting Width %d doesn't match %d", test.Width, o.Width) + } +} + func TestConvert(t *testing.T) { width, height := 300, 240 formats := [3]ImageType{PNG, WEBP, JPEG} diff --git a/vips.go b/vips.go index b9884d3..c74816f 100644 --- a/vips.go +++ b/vips.go @@ -605,7 +605,7 @@ func vipsReduce(input *C.VipsImage, xshrink float64, yshrink float64) (*C.VipsIm func vipsEmbed(input *C.VipsImage, left, top, width, height int, extend Extend, background Color) (*C.VipsImage, error) { var image *C.VipsImage - // Max extend value, see: http://www.vips.ecs.soton.ac.uk/supported/8.4/doc/html/libvips/libvips-conversion.html#VipsExtend + // Max extend value, see: https://jcupitt.github.io/libvips/API/current/libvips-conversion.html#VipsExtend if extend > 5 { extend = ExtendBackground }