You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
1.8 KiB
88 lines
1.8 KiB
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
|
|
}
|
|
|