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.
 
 
 

89 lines
1.8 KiB

  1. package media
  2. import (
  3. "fmt"
  4. "image"
  5. "regexp"
  6. "strconv"
  7. "strings"
  8. )
  9. var (
  10. sizeString = regexp.MustCompile(`([0-9]*)(x)?([0-9]*)`)
  11. )
  12. func SizeRequested(urlpath string, actual image.Rectangle) (image.Rectangle, error) {
  13. segments := strings.Count(urlpath, "/")
  14. if segments < 3 {
  15. return actual, nil
  16. }
  17. sizeSpec := strings.Split(urlpath, "/")[2]
  18. return ParseSizeString(sizeSpec, actual)
  19. }
  20. func ParseSizeString(str string, actual image.Rectangle) (image.Rectangle, error) {
  21. var err = fmt.Errorf("expected a size string {width}x{height}, saw %q", str)
  22. strs := sizeString.FindStringSubmatch(str)
  23. if len(strs) < 4 {
  24. return image.ZR, err
  25. }
  26. var w, h int
  27. var strconvErr error
  28. if strs[1] != "" {
  29. w, strconvErr = strconv.Atoi(strs[1])
  30. if strconvErr != nil {
  31. return image.ZR, err
  32. }
  33. }
  34. if strs[3] != "" {
  35. h, strconvErr = strconv.Atoi(strs[3])
  36. if strconvErr != nil {
  37. return image.ZR, err
  38. }
  39. }
  40. if strs[2] != "x" {
  41. // w was the only dimension given, so set it to the greater dimension
  42. // of the actual image size
  43. if actual.Dx() > actual.Dy() {
  44. h = 0
  45. } else {
  46. h = w
  47. w = 0
  48. }
  49. }
  50. return image.Rect(0, 0, w, h), nil
  51. }
  52. func NormalizeSize(media, requested image.Rectangle) image.Rectangle {
  53. if requested.Dx() == 0 && requested.Dy() == 0 {
  54. return media
  55. }
  56. if requested.Dy()%2 == 1 {
  57. requested.Max.Y--
  58. }
  59. if requested.Dx() != 0 && requested.Dy() != 0 {
  60. return requested
  61. }
  62. scaled := image.Rectangle{}
  63. if requested.Dx() == 0 {
  64. scaled.Max.Y = requested.Dy()
  65. scaled.Max.X = requested.Dy() * media.Dx() / media.Dy()
  66. }
  67. if requested.Dy() == 0 {
  68. scaled.Max.X = requested.Dx()
  69. scaled.Max.Y = requested.Dx() * media.Dy() / media.Dx()
  70. for scaled.Max.Y%2 == 1 {
  71. requested.Max.X--
  72. scaled.Max.X = requested.Dx()
  73. scaled.Max.Y = requested.Dx() * media.Dy() / media.Dx()
  74. }
  75. }
  76. return scaled
  77. }