From 271c23a85012ed7c460262b11ce8d26f0ac4683f Mon Sep 17 00:00:00 2001 From: Henrik Feldt Date: Mon, 21 Aug 2017 19:07:34 +0200 Subject: [PATCH] feat: extend bimg with support for autorotate http://www.vips.ecs.soton.ac.uk/supported/7.42/doc/html/libvips/libvips-conversion.html#vips-autorot --- image.go | 11 +++++++++++ options.go | 1 + resize.go | 24 ++++++++++++++++++++++++ type_test.go | 10 ++++++---- vips.go | 12 ++++++++++++ vips.h | 5 +++++ 6 files changed, 59 insertions(+), 4 deletions(-) diff --git a/image.go b/image.go index 7cff0791..ddd68fb0 100644 --- a/image.go +++ b/image.go @@ -154,6 +154,17 @@ func (i *Image) Rotate(a Angle) ([]byte, error) { return i.Process(options) } +// AutoRotate the image to be 'up' by default (setting Orientation=1) with vips. +func (i *Image) AutoRotate() ([]byte, error) { + options := Options{AutoRotate: true} + image, err := AutoRotate(i.buffer, options) + if err != nil { + return nil, err + } + i.buffer = image + return image, nil +} + // Flip flips the image about the vertical Y axis. func (i *Image) Flip() ([]byte, error) { options := Options{Flip: true} diff --git a/options.go b/options.go index d7ee592a..cd4f5621 100644 --- a/options.go +++ b/options.go @@ -204,6 +204,7 @@ type Options struct { NoAutoRotate bool NoProfile bool Interlace bool + AutoRotate bool Extend Extend Rotate Angle Background Color diff --git a/resize.go b/resize.go index 1e2725ef..cf6ab09f 100644 --- a/resize.go +++ b/resize.go @@ -11,6 +11,30 @@ import ( "math" ) +// AutoRotate is a directly calling vips. +func AutoRotate(buf []byte, o Options) ([]byte, error) { + defer C.vips_thread_shutdown() + + image, imageType, err := loadImage(buf) + if err != nil { + return nil, err + } + + // Clone and define default options + o = applyDefaults(o, imageType) + + if !IsTypeSupported(o.Type) { + return nil, errors.New("Unsupported image output type") + } + + image, err = vipsAutoRotate(image) + if err != nil { + return nil, err + } + + return saveImage(image, o) +} + // Resize is used to transform a given image as byte buffer // with the passed options. func Resize(buf []byte, o Options) ([]byte, error) { diff --git a/type_test.go b/type_test.go index 9c83b0f5..bc8f74d8 100644 --- a/type_test.go +++ b/type_test.go @@ -26,8 +26,9 @@ func TestDeterminateImageType(t *testing.T) { buf, _ := ioutil.ReadAll(img) defer img.Close() - if DetermineImageType(buf) != file.expected { - t.Fatal("Image type is not valid") + actual := DetermineImageType(buf) + if actual != file.expected { + t.Fatalf("Image type %#v does not equal the expected %#v", actual, file.expected) } } } @@ -51,8 +52,9 @@ func TestDeterminateImageTypeName(t *testing.T) { buf, _ := ioutil.ReadAll(img) defer img.Close() - if DetermineImageTypeName(buf) != file.expected { - t.Fatal("Image type is not valid") + actual := DetermineImageTypeName(buf) + if actual != file.expected { + t.Fatalf("Image type %#v does not equal the expected %#v", actual, file.expected) } } } diff --git a/vips.go b/vips.go index fc876c22..1a183405 100644 --- a/vips.go +++ b/vips.go @@ -244,6 +244,18 @@ func vipsRotate(image *C.VipsImage, angle Angle) (*C.VipsImage, error) { return out, nil } +func vipsAutoRotate(image *C.VipsImage) (*C.VipsImage, error) { + var out *C.VipsImage + defer C.g_object_unref(C.gpointer(image)) + + err := C.vips_autorotate(image, &out) + if err != 0 { + return nil, catchVipsError() + } + + return out, nil +} + func vipsFlip(image *C.VipsImage, direction Direction) (*C.VipsImage, error) { var out *C.VipsImage defer C.g_object_unref(C.gpointer(image)) diff --git a/vips.h b/vips.h index 067466e9..8ecd9d00 100644 --- a/vips.h +++ b/vips.h @@ -199,6 +199,11 @@ vips_rotate(VipsImage *in, VipsImage **out, int angle) { } } +int +vips_autorotate(VipsImage *in, VipsImage **out) { + return vips_autorot(in, out, NULL); +} + int vips_exif_orientation(VipsImage *image) { int orientation = 0;