1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2024-11-24 08:12:38 +02:00

Crop by percentage

This commit is contained in:
DarthSim 2021-01-18 21:14:15 +06:00
parent e48c557fc4
commit 9ffb0f514d
4 changed files with 36 additions and 11 deletions

View File

@ -8,6 +8,7 @@
- `IMGPROXY_FORMAT_QUALITY` config.
- `IMGPROXY_AUTO_ROTATE` config and [auto_rotate](https://docs.imgproxy.net/#/generating_the_url_advanced?id=auto-rotate) processing option.
- [rotate](https://docs.imgproxy.net/#/generating_the_url_advanced?id=rotate) processing option.
- `width` and `height` arguments of the [crop](https://docs.imgproxy.net/#/generating_the_url_advanced?id=crop) processing option can be less than `1` that is treated by imgproxy as a relative value (a.k.a. crop by percentage).
- (pro) Remove Adobe Illustrator garbage from SVGs.
### Changed

View File

@ -167,7 +167,10 @@ c:%width:%height:%gravity
Defines an area of the image to be processed (crop before resize).
* `width` and `height` define the size of the area. When `width` or `height` is set to `0`, imgproxy will use the full width/height of the source image.
* `width` and `height` define the size of the area:
* When `width` or `height` is greater than or equal to `1`, imgproxy treats it as an absolute value.
* When `width` or `height` is less than `1`, imgproxy treats it as a relative value.
* When `width` or `height` is set to `0`, imgproxy will use the full width/height of the source image.
* `gravity` _(optional)_ accepts the same values as [gravity](#gravity) option. When `gravity` is not set, imgproxy will use the value of the [gravity](#gravity) option.
#### Padding

View File

@ -163,6 +163,17 @@ func calcJpegShink(scale float64, imgtype imageType) int {
return 1
}
func calcCropSize(orig int, crop float64) int {
switch {
case crop == 0.0:
return 0
case crop >= 1.0:
return int(crop)
default:
return maxInt(1, scaleInt(orig, crop))
}
}
func calcPosition(width, height, innerWidth, innerHeight int, gravity *gravityOptions, allowOverflow bool) (left, top int) {
if gravity.Type == gravityFocusPoint {
pointX := scaleInt(width, gravity.X)
@ -325,7 +336,9 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
}
srcWidth, srcHeight, angle, flip := extractMeta(img, po.Rotate, po.AutoRotate)
cropWidth, cropHeight := po.Crop.Width, po.Crop.Height
cropWidth := calcCropSize(srcWidth, po.Crop.Width)
cropHeight := calcCropSize(srcHeight, po.Crop.Height)
cropGravity := po.Crop.Gravity
if cropGravity.Type == gravityUnknown {
@ -337,8 +350,12 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
scale := calcScale(widthToScale, heightToScale, po, imgtype)
cropWidth = scaleInt(cropWidth, scale)
cropHeight = scaleInt(cropHeight, scale)
if cropWidth > 0 {
cropWidth = maxInt(1, scaleInt(cropWidth, scale))
}
if cropHeight > 0 {
cropHeight = maxInt(1, scaleInt(cropHeight, scale))
}
if cropGravity.Type != gravityFocusPoint {
cropGravity.X *= scale
cropGravity.Y *= scale
@ -773,7 +790,7 @@ func processImage(ctx context.Context) ([]byte, context.CancelFunc, error) {
if po.ResizingType == resizeCrop {
logWarning("`crop` resizing type is deprecated and will be removed in future versions. Use `crop` processing option instead")
po.Crop.Width, po.Crop.Height = po.Width, po.Height
po.Crop.Width, po.Crop.Height = float64(po.Width), float64(po.Height)
po.ResizingType = resizeFit
po.Width, po.Height = 0, 0

View File

@ -95,8 +95,8 @@ type extendOptions struct {
}
type cropOptions struct {
Width int
Height int
Width float64
Height float64
Gravity gravityOptions
}
@ -571,13 +571,17 @@ func applyCropOption(po *processingOptions, args []string) error {
return fmt.Errorf("Invalid crop arguments: %v", args)
}
if err := parseDimension(&po.Crop.Width, "crop width", args[0]); err != nil {
return err
if w, err := strconv.ParseFloat(args[0], 64); err == nil && w >= 0 {
po.Crop.Width = w
} else {
return fmt.Errorf("Invalid crop width: %s", args[0])
}
if len(args) > 1 {
if err := parseDimension(&po.Crop.Height, "crop height", args[1]); err != nil {
return err
if h, err := strconv.ParseFloat(args[1], 64); err == nil && h >= 0 {
po.Crop.Height = h
} else {
return fmt.Errorf("Invalid crop height: %s", args[1])
}
}