From e7b0a5b88cb8fb82c0d7c1ce2d969ea3235205e2 Mon Sep 17 00:00:00 2001 From: Pete Smith Date: Mon, 12 Jan 2015 17:32:00 +0000 Subject: [PATCH] Add quality option - Added 'q' option to specify quality (used for JPEGs) - Updated tests - Update documentation --- README.md | 6 ++++++ data.go | 14 ++++++++++++++ data_test.go | 14 +++++++------- transform.go | 8 +++++++- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 783a095..0a721b2 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,11 @@ The `r{degrees}` option will rotate the image the specified number of degrees, counter-clockwise. Valid degrees values are `90`, `180`, and `270`. Images are rotated **after** being resized. +#### Quality #### + +The `q{percentage}` option can be used to specify the output quality (JPEG +only). + #### Flip #### The `fv` option will flip the image vertically. The `fh` option will flip the @@ -99,6 +104,7 @@ x100 | 100px tall, proportional width | 150,fit 100,r90 | 100px square, rotated 90 degrees | 100,r90 100,fv,fh | 100px square, flipped horizontal and vertical | 100,fv,fh +200x,q60 | 200px wide, proportional height, 60% quality | 200x,q60 ## Getting Started ## diff --git a/data.go b/data.go index 59121bf..c1f9af0 100644 --- a/data.go +++ b/data.go @@ -28,6 +28,7 @@ const ( optFlipVertical = "fv" optFlipHorizontal = "fh" optRotatePrefix = "r" + optQualityPrefix = "q" optSizeDelimiter = "x" ) @@ -57,6 +58,9 @@ type Options struct { FlipVertical bool FlipHorizontal bool + + // Quality of output image + Quality int } var emptyOptions = Options{} @@ -76,6 +80,7 @@ func (o Options) String() string { if o.FlipHorizontal { fmt.Fprintf(buf, ",%s", optFlipHorizontal) } + fmt.Fprintf(buf, ",%s%d", string(optQualityPrefix), o.Quality) return buf.String() } @@ -119,6 +124,11 @@ func (o Options) String() string { // The "fv" option will flip the image vertically. The "fh" option will flip // the image horizontally. Images are flipped after being rotated. // +// Quality +// +// The "q{qualityPercentage}" option can be used to specify the quality of the +// output file (JPEG only) +// // Examples // // 0x0 - no resizing @@ -130,6 +140,7 @@ func (o Options) String() string { // 150,fit - scale to fit 150 pixels square, no cropping // 100,r90 - 100 pixels square, rotated 90 degrees // 100,fv,fh - 100 pixels square, flipped horizontal and vertical +// 200x,q80 - 200 pixels wide, proportional height, 80% quality func ParseOptions(str string) Options { options := Options{} @@ -146,6 +157,9 @@ func ParseOptions(str string) Options { case strings.HasPrefix(opt, optRotatePrefix): value := strings.TrimPrefix(opt, optRotatePrefix) options.Rotate, _ = strconv.Atoi(value) + case strings.HasPrefix(opt, optQualityPrefix): + value := strings.TrimPrefix(opt, optQualityPrefix) + options.Quality, _ = strconv.Atoi(value) case strings.Contains(opt, optSizeDelimiter): size := strings.SplitN(opt, optSizeDelimiter, 2) if w := size[0]; w != "" { diff --git a/data_test.go b/data_test.go index 4e4b4b4..2f86ad2 100644 --- a/data_test.go +++ b/data_test.go @@ -26,15 +26,15 @@ func TestOptions_String(t *testing.T) { }{ { emptyOptions, - "0x0", + "0x0,q0", }, { - Options{1, 2, true, 90, true, true}, - "1x2,fit,r90,fv,fh", + Options{1, 2, true, 90, true, true, 80}, + "1x2,fit,r90,fv,fh,q80", }, { - Options{0.15, 1.3, false, 45, false, false}, - "0.15x1.3,r45", + Options{0.15, 1.3, false, 45, false, false, 95}, + "0.15x1.3,r45,q95", }, } @@ -82,8 +82,8 @@ func TestParseOptions(t *testing.T) { {"FOO,1,BAR,r90,BAZ", Options{Width: 1, Height: 1, Rotate: 90}}, // all flags, in different orders - {"1x2,fit,r90,fv,fh", Options{1, 2, true, 90, true, true}}, - {"r90,fh,1x2,fv,fit", Options{1, 2, true, 90, true, true}}, + {"q70,1x2,fit,r90,fv,fh", Options{1, 2, true, 90, true, true, 70}}, + {"r90,fh,q90,1x2,fv,fit", Options{1, 2, true, 90, true, true, 90}}, } for _, tt := range tests { diff --git a/transform.go b/transform.go index 20a010e..2f6840d 100644 --- a/transform.go +++ b/transform.go @@ -53,7 +53,13 @@ func Transform(img []byte, opt Options) ([]byte, error) { case "gif": gif.Encode(buf, m, nil) case "jpeg": - jpeg.Encode(buf, m, &jpeg.Options{Quality: jpegQuality}) + quality := opt.Quality + + if quality == 0 { + quality = jpegQuality + } + + jpeg.Encode(buf, m, &jpeg.Options{Quality: quality}) case "png": png.Encode(buf, m) }