mirror of
https://github.com/imgproxy/imgproxy.git
synced 2024-11-24 08:12:38 +02:00
Implement padding option (#358)
* Implement padding option * Move padding `embed` to the right place * Move padding `embed` to the right place * Use general background option instead of specific padding's one * Make padding options css-like and fully optional * Add docs for new padding option * Return error if padding embed fails * Make padding outbounds and apply dpr for it Co-authored-by: Ilya Melnitskiy <melnitskiy_i_m@onyx-team.com>
This commit is contained in:
parent
026fb617b1
commit
12b415c9bd
@ -170,6 +170,24 @@ 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.
|
||||
* `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
|
||||
|
||||
```
|
||||
padding:%top:%right:%bottom:%left
|
||||
pd:%top:%right:%bottom:%left
|
||||
```
|
||||
|
||||
Defines padding size in css manner. All arguments are optional but at least one dimension must be set. Padded space is filled according to [background](#background) option.
|
||||
|
||||
* `top` - top padding (and all other sides if they won't be set explicitly);
|
||||
* `right` - right padding (and left if it won't be set explicitly);
|
||||
* `bottom` - bottom padding;
|
||||
* `left` - left padding.
|
||||
|
||||
**📝Notes:**
|
||||
* Padding is applied after all image transformations (except watermark) and enlarges generated image which means that if your resize dimensions were 100x200px and you applied `padding:10` option then you will get 120x220px image.
|
||||
* Padding follows [dpr](#dpr) option so it will be scaled too if you set it.
|
||||
|
||||
#### Trim
|
||||
|
||||
```
|
||||
|
16
process.go
16
process.go
@ -453,6 +453,22 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
|
||||
}
|
||||
}
|
||||
|
||||
if po.Padding.Enabled {
|
||||
paddingTop := scaleInt(po.Padding.Top, po.Dpr)
|
||||
paddingRight := scaleInt(po.Padding.Right, po.Dpr)
|
||||
paddingBottom := scaleInt(po.Padding.Bottom, po.Dpr)
|
||||
paddingLeft := scaleInt(po.Padding.Left, po.Dpr)
|
||||
if err = img.Embed(
|
||||
img.Width()+paddingLeft+paddingRight,
|
||||
img.Height()+paddingTop+paddingBottom,
|
||||
paddingLeft,
|
||||
paddingTop,
|
||||
po.Background,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
checkTimeout(ctx)
|
||||
|
||||
if po.Watermark.Enabled && watermark != nil {
|
||||
|
@ -100,6 +100,14 @@ type cropOptions struct {
|
||||
Gravity gravityOptions
|
||||
}
|
||||
|
||||
type paddingOptions struct {
|
||||
Enabled bool
|
||||
Top int
|
||||
Right int
|
||||
Bottom int
|
||||
Left int
|
||||
}
|
||||
|
||||
type trimOptions struct {
|
||||
Enabled bool
|
||||
Threshold float64
|
||||
@ -126,6 +134,7 @@ type processingOptions struct {
|
||||
Enlarge bool
|
||||
Extend extendOptions
|
||||
Crop cropOptions
|
||||
Padding paddingOptions
|
||||
Trim trimOptions
|
||||
Format imageType
|
||||
Quality int
|
||||
@ -208,6 +217,7 @@ func newProcessingOptions() *processingOptions {
|
||||
Gravity: gravityOptions{Type: gravityCenter},
|
||||
Enlarge: false,
|
||||
Extend: extendOptions{Enabled: false, Gravity: gravityOptions{Type: gravityCenter}},
|
||||
Padding: paddingOptions{Enabled: false},
|
||||
Trim: trimOptions{Enabled: false, Threshold: 10, Smart: true},
|
||||
Quality: conf.Quality,
|
||||
MaxBytes: 0,
|
||||
@ -556,6 +566,50 @@ func applyCropOption(po *processingOptions, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyPaddingOption(po *processingOptions, args []string) error {
|
||||
nArgs := len(args)
|
||||
|
||||
if nArgs < 1 || nArgs > 4 {
|
||||
return fmt.Errorf("Invalid padding arguments: %v", args)
|
||||
}
|
||||
|
||||
po.Padding.Enabled = true
|
||||
|
||||
if nArgs > 0 && len(args[0]) > 0 {
|
||||
if err := parseDimension(&po.Padding.Top, "padding top (+all)", args[0]); err != nil {
|
||||
return err
|
||||
}
|
||||
po.Padding.Right = po.Padding.Top
|
||||
po.Padding.Bottom = po.Padding.Top
|
||||
po.Padding.Left = po.Padding.Top
|
||||
}
|
||||
|
||||
if nArgs > 1 && len(args[1]) > 0 {
|
||||
if err := parseDimension(&po.Padding.Right, "padding right (+left)", args[1]); err != nil {
|
||||
return err
|
||||
}
|
||||
po.Padding.Left = po.Padding.Right
|
||||
}
|
||||
|
||||
if nArgs > 2 && len(args[2]) > 0 {
|
||||
if err := parseDimension(&po.Padding.Bottom, "padding bottom", args[2]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if nArgs > 3 && len(args[3]) > 0 {
|
||||
if err := parseDimension(&po.Padding.Left, "padding left", args[3]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if po.Padding.Top == 0 && po.Padding.Right == 0 && po.Padding.Bottom == 0 && po.Padding.Left == 0 {
|
||||
po.Padding.Enabled = false
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyTrimOption(po *processingOptions, args []string) error {
|
||||
nArgs := len(args)
|
||||
|
||||
@ -820,6 +874,8 @@ func applyProcessingOption(po *processingOptions, name string, args []string) er
|
||||
return applyCropOption(po, args)
|
||||
case "trim", "t":
|
||||
return applyTrimOption(po, args)
|
||||
case "padding", "pd":
|
||||
return applyPaddingOption(po, args)
|
||||
case "quality", "q":
|
||||
return applyQualityOption(po, args)
|
||||
case "max_bytes", "mb":
|
||||
|
Loading…
Reference in New Issue
Block a user