diff --git a/pkg/processor/interface.go b/pkg/processor/interface.go index 4b1fa45..bcc4983 100644 --- a/pkg/processor/interface.go +++ b/pkg/processor/interface.go @@ -8,6 +8,9 @@ type Processor interface { Crop(image image.Image, width, height int, point CropPoint) image.Image // Resize takes an image.Image, width and height and returns the re-sized image Resize(image image.Image, width, height int) image.Image + // Scale takes an input image, width and height and returns the re-sized + // image without maintaining the original aspect ratio + Scale(image image.Image, width, height int) image.Image // GrayScale takes an input byte array and returns the grayscaled byte array or error GrayScale(image image.Image) image.Image // Blur takes an input byte array and returns the blurred byte array by the specified diff --git a/pkg/processor/native/_testdata/test_scaled.jpg b/pkg/processor/native/_testdata/test_scaled.jpg new file mode 100644 index 0000000..9fb1e8b Binary files /dev/null and b/pkg/processor/native/_testdata/test_scaled.jpg differ diff --git a/pkg/processor/native/processor.go b/pkg/processor/native/processor.go index 3cc51c5..6d7d9fa 100644 --- a/pkg/processor/native/processor.go +++ b/pkg/processor/native/processor.go @@ -58,6 +58,12 @@ func (bp *BildProcessor) Resize(img image.Image, width, height int) image.Image return img } +// Scale takes an input image, width and height and returns the re-sized +// image without maintaining the original aspect ratio +func (bp *BildProcessor) Scale(img image.Image, width, height int) image.Image { + return transform.Resize(img, width, height, transform.Linear) +} + // Watermark takes an input byte array, overlay byte array and opacity value // and returns the watermarked image bytes or error func (bp *BildProcessor) Watermark(base []byte, overlay []byte, opacity uint8) ([]byte, error) { diff --git a/pkg/processor/native/processor_test.go b/pkg/processor/native/processor_test.go index 0a914c8..5ce521c 100644 --- a/pkg/processor/native/processor_test.go +++ b/pkg/processor/native/processor_test.go @@ -50,6 +50,14 @@ func (s *BildProcessorSuite) TestBildProcessor_ResizeWithSameWidthAndHeight() { assert.Equal(s.T(), &s.srcImage, &out) } +func (s *BildProcessorSuite) TestBildProcessor_Scale() { + actual := s.processor.Scale(s.srcImage, 1000, 1000) + encoded, _ := s.processor.Encode(actual, "jpg") + expected, _ := ioutil.ReadFile("_testdata/test_scaled.jpg") + + assert.Equal(s.T(), encoded, expected) +} + func (s *BildProcessorSuite) TestBildProcessor_Crop() { cases := []struct { w int diff --git a/pkg/service/manipulator.go b/pkg/service/manipulator.go index 7179681..0ab8cd9 100644 --- a/pkg/service/manipulator.go +++ b/pkg/service/manipulator.go @@ -27,6 +27,7 @@ const ( blur = "blur" compress = "compress" format = "format" + scale = "scale" cropDurationKey = "cropDuration" decodeDurationKey = "decodeDuration" @@ -37,6 +38,7 @@ const ( flipDurationKey = "flipDuration" rotateDurationKey = "rotateDuration" fixOrientationKey = "fixOrientation" + scaleDurationKey = "scaleDuration" ) // Manipulator interface sets the contract on the implementation for common processing support in darkroom @@ -66,11 +68,16 @@ func (m *manipulator) Process(spec processSpec) ([]byte, error) { t = time.Now() data = m.processor.Crop(data, CleanInt(params[width]), CleanInt(params[height]), GetCropPoint(params[crop])) trackDuration(cropDurationKey, t, spec) + } else if params[fit] == scale { + t = time.Now() + data = m.processor.Scale(data, CleanInt(params[width]), CleanInt(params[height])) + trackDuration(scaleDurationKey, t, spec) } else if len(params[fit]) == 0 && (CleanInt(params[width]) != 0 || CleanInt(params[height]) != 0) { t = time.Now() data = m.processor.Resize(data, CleanInt(params[width]), CleanInt(params[height])) trackDuration(resizeDurationKey, t, spec) } + if params[mono] == blackHexCode { t = time.Now() data = m.processor.GrayScale(data) diff --git a/pkg/service/manipulator_test.go b/pkg/service/manipulator_test.go index 546fc48..9413107 100644 --- a/pkg/service/manipulator_test.go +++ b/pkg/service/manipulator_test.go @@ -86,6 +86,13 @@ func TestManipulator_Process(t *testing.T) { params[height] = "100" _, _ = m.Process(NewSpecBuilder().WithImageData(input).WithParams(params).Build()) + mp.On("Scale", decoded, 100, 100).Return(decoded, nil) + params = make(map[string]string) + params[width] = "100" + params[height] = "100" + params[fit] = scale + _, _ = m.Process(NewSpecBuilder().WithImageData(input).WithParams(params).Build()) + mp.On("GrayScale", decoded).Return(decoded, nil) params = make(map[string]string) params[mono] = blackHexCode @@ -199,6 +206,11 @@ func (m *mockProcessor) Resize(img image.Image, width, height int) image.Image { return args.Get(0).(image.Image) } +func (m *mockProcessor) Scale(img image.Image, width, height int) image.Image { + args := m.Called(img, width, height) + return args.Get(0).(image.Image) +} + func (m *mockProcessor) Watermark(base []byte, overlay []byte, opacity uint8) ([]byte, error) { args := m.Called(base, overlay, opacity) return args.Get(0).([]byte), args.Get(1).(error)