0
Fork 0
mirror of https://github.com/willnorris/imageproxy.git synced 2025-01-06 22:40:34 -05:00

accept "fit" option

this also relaxes option parsing to never return an error.  In cases
where options are not able to be parsed, they are silently ignored.
This commit is contained in:
Will Norris 2013-12-06 11:01:34 -08:00
parent 805aa606ca
commit 2794d47390
4 changed files with 47 additions and 23 deletions

View file

@ -2,7 +2,6 @@
package data
import (
"errors"
"fmt"
"net/url"
"strconv"
@ -15,18 +14,24 @@ import (
type Options struct {
Width int // requested width, in pixels
Height int // requested height, in pixels
// If true, resize the image to fit in the specified dimensions. Image
// will not be cropped, and aspect ratio will be maintained.
Fit bool
}
func (o Options) String() string {
return fmt.Sprintf("%dx%d", o.Width, o.Height)
}
func ParseOptions(str string) (*Options, error) {
t := new(Options)
var err error
func ParseOptions(str string) *Options {
o := new(Options)
var h, w string
size := strings.SplitN(str, "x", 2)
parts := strings.Split(str, ",")
// parse size
size := strings.SplitN(parts[0], "x", 2)
w = size[0]
if len(size) > 1 {
h = size[1]
@ -35,19 +40,19 @@ func ParseOptions(str string) (*Options, error) {
}
if w != "" {
t.Width, err = strconv.Atoi(w)
if err != nil {
return nil, errors.New("width must be an int")
}
o.Width, _ = strconv.Atoi(w)
}
if h != "" {
t.Height, err = strconv.Atoi(h)
if err != nil {
return nil, errors.New("height must be an int")
o.Height, _ = strconv.Atoi(h)
}
for _, part := range parts[1:] {
if part == "fit" {
o.Fit = true
}
}
return t, nil
return o
}
type Request struct {

View file

@ -46,10 +46,7 @@ func NewRequest(r *http.Request) (*data.Request, error) {
return nil, URLError{fmt.Sprintf("unable to parse remote URL: %v", err), r.URL}
}
req.Options, err = data.ParseOptions(parts[0])
if err != nil {
return nil, URLError{err.Error(), r.URL}
}
req.Options = data.ParseOptions(parts[0])
}
if !req.URL.IsAbs() {

View file

@ -30,11 +30,15 @@ func TestNewRequest(t *testing.T) {
{
"http://localhost//ftp://example.com/foo", "", nil, true,
},
// invalid options. These won't return errors, but will not fully parse the options
{
"http://localhost/s/http://example.com/", "", nil, true,
"http://localhost/s/http://example.com/",
"http://example.com/", emptyOptions, false,
},
{
"http://localhost/1xs/http://example.com/", "", nil, true,
"http://localhost/1xs/http://example.com/",
"http://example.com/", &data.Options{Width: 1}, false,
},
// valid URLs
@ -66,15 +70,23 @@ func TestNewRequest(t *testing.T) {
},
{
"http://localhost/1x/http://example.com/",
"http://example.com/", &data.Options{1, 0}, false,
"http://example.com/", &data.Options{1, 0, false}, false,
},
{
"http://localhost/x1/http://example.com/",
"http://example.com/", &data.Options{0, 1}, false,
"http://example.com/", &data.Options{0, 1, false}, false,
},
{
"http://localhost/1x2/http://example.com/",
"http://example.com/", &data.Options{1, 2}, false,
"http://example.com/", &data.Options{1, 2, false}, false,
},
{
"http://localhost/,fit/http://example.com/",
"http://example.com/", &data.Options{0, 0, true}, false,
},
{
"http://localhost/1x2,fit/http://example.com/",
"http://example.com/", &data.Options{1, 2, true}, false,
},
}

View file

@ -18,6 +18,14 @@ var emptyOptions = new(data.Options)
// Transform the provided image.
func Transform(img data.Image, opt *data.Options) (*data.Image, error) {
if opt == nil || reflect.DeepEqual(opt, emptyOptions) {
// bail if no transformation was requested
return &img, nil
}
if opt.Width == 0 && opt.Height == 0 {
// TODO(willnorris): Currently, only resize related options are
// supported, so bail if no sizes are specified. Remove this
// check if we ever support non-resizing transformations.
return &img, nil
}
@ -28,8 +36,10 @@ func Transform(img data.Image, opt *data.Options) (*data.Image, error) {
}
// resize
if opt.Width != 0 || opt.Height != 0 {
if opt.Fit {
m = imaging.Fit(m, opt.Width, opt.Height, imaging.Lanczos)
} else {
m = imaging.Resize(m, opt.Width, opt.Height, imaging.Lanczos)
}
// encode image