From dd1df4631b8295d29f5b03857d0e38f0d050ca17 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Thu, 4 Dec 2014 10:34:26 -0800 Subject: [PATCH] add tests for transformImage --- transform.go | 9 ++- transform_test.go | 138 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 transform_test.go diff --git a/transform.go b/transform.go index c47394e..20a010e 100644 --- a/transform.go +++ b/transform.go @@ -27,6 +27,9 @@ import ( // compression quality of resized jpegs const jpegQuality = 95 +// resample filter used when resizing images +var resampleFilter = imaging.Lanczos + // Transform the provided image. img should contain the raw bytes of an // encoded image in one of the supported formats (gif, jpeg, or png). The // bytes of a similarly encoded image is returned. @@ -91,12 +94,12 @@ func transformImage(m image.Image, opt Options) image.Image { // resize if w != 0 || h != 0 { if opt.Fit { - m = imaging.Fit(m, w, h, imaging.Lanczos) + m = imaging.Fit(m, w, h, resampleFilter) } else { if w == 0 || h == 0 { - m = imaging.Resize(m, w, h, imaging.Lanczos) + m = imaging.Resize(m, w, h, resampleFilter) } else { - m = imaging.Thumbnail(m, w, h, imaging.Lanczos) + m = imaging.Thumbnail(m, w, h, resampleFilter) } } } diff --git a/transform_test.go b/transform_test.go new file mode 100644 index 0000000..750b11c --- /dev/null +++ b/transform_test.go @@ -0,0 +1,138 @@ +package imageproxy + +import ( + "image" + "image/color" + "image/draw" + "reflect" + "testing" + + "github.com/disintegration/imaging" +) + +var ( + red = color.NRGBA{255, 0, 0, 255} + green = color.NRGBA{0, 255, 0, 255} + blue = color.NRGBA{0, 0, 255, 255} + yellow = color.NRGBA{255, 255, 0, 255} +) + +// newImage creates a new NRGBA image with the specified dimensions and pixel +// color data. If the length of pixels is 1, the entire image is filled with +// that color. +func newImage(w, h int, pixels ...color.NRGBA) image.Image { + m := image.NewNRGBA(image.Rect(0, 0, w, h)) + if len(pixels) == 1 { + draw.Draw(m, m.Bounds(), &image.Uniform{pixels[0]}, image.ZP, draw.Src) + } else { + for i, p := range pixels { + m.Set(i%w, i/w, p) + } + } + return m +} + +func TestTransformImage(t *testing.T) { + // ref is a 2x2 reference image containing four colors + ref := newImage(2, 2, red, green, blue, yellow) + + // use simpler filter while testing that won't skew colors + resampleFilter = imaging.Box + + tests := []struct { + src image.Image // source image to transform + opt Options // options to apply during transform + want image.Image // expected transformed image + }{ + // no transformation + {ref, emptyOptions, ref}, + + // rotations + {ref, Options{Rotate: 45}, ref}, // invalid rotation is a noop + {ref, Options{Rotate: 90}, newImage(2, 2, green, yellow, red, blue)}, + {ref, Options{Rotate: 180}, newImage(2, 2, yellow, blue, green, red)}, + {ref, Options{Rotate: 270}, newImage(2, 2, blue, red, yellow, green)}, + + // flips + { + ref, + Options{FlipHorizontal: true}, + newImage(2, 2, green, red, yellow, blue), + }, + { + ref, + Options{FlipVertical: true}, + newImage(2, 2, blue, yellow, red, green), + }, + { + ref, + Options{FlipHorizontal: true, FlipVertical: true}, + newImage(2, 2, yellow, blue, green, red), + }, + + // resizing + { // can't resize larger than original image + ref, + Options{Width: 100, Height: 100}, + ref, + }, + { // invalid values + ref, + Options{Width: -1, Height: -1}, + ref, + }, + { // absolute values + newImage(100, 100, red), + Options{Width: 1, Height: 1}, + newImage(1, 1, red), + }, + { // percentage values + newImage(100, 100, red), + Options{Width: 0.50, Height: 0.25}, + newImage(50, 25, red), + }, + { // only width specified, proportional height + newImage(100, 50, red), + Options{Width: 50}, + newImage(50, 25, red), + }, + { // only height specified, proportional width + newImage(100, 50, red), + Options{Height: 25}, + newImage(50, 25, red), + }, + { // resize in one dimenstion, with cropping + newImage(4, 2, red, red, blue, blue, red, red, blue, blue), + Options{Width: 4, Height: 1}, + newImage(4, 1, red, red, blue, blue), + }, + { // resize in two dimensions, with cropping + newImage(4, 2, red, red, blue, blue, red, red, blue, blue), + Options{Width: 2, Height: 2}, + newImage(2, 2, red, blue, red, blue), + }, + { // resize in two dimensions, fit option prevents cropping + newImage(4, 2, red, red, blue, blue, red, red, blue, blue), + Options{Width: 2, Height: 2, Fit: true}, + newImage(2, 1, red, blue), + }, + { // scale image explicitly + newImage(4, 2, red, red, blue, blue, red, red, blue, blue), + Options{Width: 2, Height: 1}, + newImage(2, 1, red, blue), + }, + + // combinations of options + { + newImage(4, 2, red, red, blue, blue, red, red, blue, blue), + Options{Width: 2, Height: 1, Fit: true, FlipHorizontal: true, Rotate: 90}, + newImage(1, 2, red, blue), + }, + } + + for _, tt := range tests { + if got := transformImage(tt.src, tt.opt); !reflect.DeepEqual(got, tt.want) { + t.Errorf("trasformImage(%v, %v) returned image %#v, want %#v", tt.src, tt.opt, got, tt.want) + } + } +}