package media import ( "fmt" "image" "regexp" "strconv" "strings" ) var ( sizeString = regexp.MustCompile(`([0-9]*)(x)?([0-9]*)`) ) func SizeRequested(urlpath string, actual image.Rectangle) (image.Rectangle, error) { segments := strings.Count(urlpath, "/") if segments < 3 { return actual, nil } sizeSpec := strings.Split(urlpath, "/")[2] return ParseSizeString(sizeSpec, actual) } func ParseSizeString(str string, actual image.Rectangle) (image.Rectangle, error) { var err = fmt.Errorf("expected a size string {width}x{height}, saw %q", str) strs := sizeString.FindStringSubmatch(str) if len(strs) < 4 { return image.ZR, err } var w, h int var strconvErr error if strs[1] != "" { w, strconvErr = strconv.Atoi(strs[1]) if strconvErr != nil { return image.ZR, err } } if strs[3] != "" { h, strconvErr = strconv.Atoi(strs[3]) if strconvErr != nil { return image.ZR, err } } if strs[2] != "x" { // w was the only dimension given, so set it to the greater dimension // of the actual image size if actual.Dx() > actual.Dy() { h = 0 } else { h = w w = 0 } } return image.Rect(0, 0, w, h), nil } func NormalizeSize(media, requested image.Rectangle) image.Rectangle { if requested.Dx() == 0 && requested.Dy() == 0 { return media } if requested.Dy()%2 == 1 { requested.Max.Y-- } if requested.Dx() != 0 && requested.Dy() != 0 { return requested } scaled := image.Rectangle{} if requested.Dx() == 0 { scaled.Max.Y = requested.Dy() scaled.Max.X = requested.Dy() * media.Dx() / media.Dy() } if requested.Dy() == 0 { scaled.Max.X = requested.Dx() scaled.Max.Y = requested.Dx() * media.Dy() / media.Dx() for scaled.Max.Y%2 == 1 { requested.Max.X-- scaled.Max.X = requested.Dx() scaled.Max.Y = requested.Dx() * media.Dy() / media.Dx() } } return scaled }