mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-01-03 10:43:58 +02:00
Watermark scale
This commit is contained in:
parent
fe4810609a
commit
c049fb8a28
@ -162,8 +162,8 @@ Default: disabled
|
||||
##### Watermark
|
||||
|
||||
```
|
||||
watermark:%opacity:%position:%x_offset:%y_offset
|
||||
wm:%opacity:%position:%x_offset:%y_offset
|
||||
watermark:%opacity:%position:%x_offset:%y_offset:%scale
|
||||
wm:%opacity:%position:%x_offset:%y_offset:%scale
|
||||
```
|
||||
|
||||
Puts watermark on the processed image.
|
||||
@ -180,7 +180,8 @@ Puts watermark on the processed image.
|
||||
* `soea`: south-east (bottom-right corner);
|
||||
* `sowe`: south-west (bottom-left corner);
|
||||
* `re`: replicate watermark to fill the whole image;
|
||||
* `x_offset`, `y_offset` - (optional) specify watermark offset by X and Y axes. Not applicable to `re` position.
|
||||
* `x_offset`, `y_offset` - (optional) specify watermark offset by X and Y axes. Not applicable to `re` position;
|
||||
* `scale` - (optional) floating point number that defines watermark size relative to the resulting image size. When set to `0` or omitted, watermark size won't be changed.
|
||||
|
||||
Default: disabled
|
||||
|
||||
|
@ -17,8 +17,8 @@ You can also specify the base opacity of watermark with `IMGPROXY_WATERMARK_OPAC
|
||||
Watermarks are only available with [advanced URL format](generating_the_url_advanced.md). Use `watermark` processing option to put the watermark on the processed image:
|
||||
|
||||
```
|
||||
watermark:%opacity:%position:%x_offset:%y_offset
|
||||
wm:%opacity:%position:%x_offset:%y_offset
|
||||
watermark:%opacity:%position:%x_offset:%y_offset:%scale
|
||||
wm:%opacity:%position:%x_offset:%y_offset:%scale
|
||||
```
|
||||
|
||||
Where arguments are:
|
||||
@ -35,4 +35,5 @@ Where arguments are:
|
||||
* `soea`: south-east (bottom-right corner);
|
||||
* `sowe`: south-west (bottom-left corner);
|
||||
* `re`: replicate watermark to fill the whole image;
|
||||
* `x_offset`, `y_offset` - (optional) specify watermark offset by X and Y axes. Not applicable to `re` position.
|
||||
* `x_offset`, `y_offset` - (optional) specify watermark offset by X and Y axes. Not applicable to `re` position;
|
||||
* `scale` - (optional) floating point number that defines watermark size relative to the resulting image size. When set to `0` or omitted, watermark size won't be changed.
|
||||
|
69
process.go
69
process.go
@ -635,26 +635,25 @@ func vipsImageCopyMemory(img **C.struct__VipsImage) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func vipsReplicateWatermark(width, height C.int) (wm *C.struct__VipsImage, err error) {
|
||||
func vipsReplicate(img **C.struct__VipsImage, width, height C.int) error {
|
||||
var tmp *C.struct__VipsImage
|
||||
defer C.clear_image(&tmp)
|
||||
|
||||
if C.vips_replicate_go(watermark, &tmp, 1+width/watermark.Xsize, 1+height/watermark.Ysize) != 0 {
|
||||
err = vipsError()
|
||||
return
|
||||
if C.vips_replicate_go(*img, &tmp, 1+width/(*img).Xsize, 1+height/(*img).Ysize) != 0 {
|
||||
return vipsError()
|
||||
}
|
||||
C.swap_and_clear(img, tmp)
|
||||
|
||||
if C.vips_extract_area_go(tmp, &wm, 0, 0, width, height) != 0 {
|
||||
err = vipsError()
|
||||
return
|
||||
if C.vips_extract_area_go(*img, &tmp, 0, 0, width, height) != 0 {
|
||||
return vipsError()
|
||||
}
|
||||
C.swap_and_clear(img, tmp)
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
func vipsEmbedWatermark(gravity gravityType, width, height C.int, offX, offY C.int) (wm *C.struct__VipsImage, err error) {
|
||||
wmWidth := watermark.Xsize
|
||||
wmHeight := watermark.Ysize
|
||||
func vipsEmbed(img **C.struct__VipsImage, gravity gravityType, width, height C.int, offX, offY C.int) error {
|
||||
wmWidth := (*img).Xsize
|
||||
wmHeight := (*img).Ysize
|
||||
|
||||
left := (width-wmWidth+1)/2 + offX
|
||||
top := (height-wmHeight+1)/2 + offY
|
||||
@ -687,9 +686,34 @@ func vipsEmbedWatermark(gravity gravityType, width, height C.int, offX, offY C.i
|
||||
top = 0
|
||||
}
|
||||
|
||||
if C.vips_embed_go(watermark, &wm, left, top, width, height) != 0 {
|
||||
var tmp *C.struct__VipsImage
|
||||
if C.vips_embed_go(*img, &tmp, left, top, width, height) != 0 {
|
||||
return vipsError()
|
||||
}
|
||||
C.swap_and_clear(img, tmp)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func vipsResizeWatermark(width, height int) (wm *C.struct__VipsImage, err error) {
|
||||
wmW := float64(watermark.Xsize)
|
||||
wmH := float64(watermark.Ysize)
|
||||
|
||||
wr := float64(width) / wmW
|
||||
hr := float64(height) / wmH
|
||||
|
||||
scale := math.Min(wr, hr)
|
||||
|
||||
if wmW*scale < 1 {
|
||||
scale = 1 / wmW
|
||||
}
|
||||
|
||||
if wmH*scale < 1 {
|
||||
scale = 1 / wmH
|
||||
}
|
||||
|
||||
if C.vips_resize_go(watermark, &wm, C.double(scale)) != 0 {
|
||||
err = vipsError()
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
@ -709,12 +733,25 @@ func vipsApplyWatermark(img **C.struct__VipsImage, opts *watermarkOptions) error
|
||||
imgW := (*img).Xsize
|
||||
imgH := (*img).Ysize
|
||||
|
||||
if opts.Scale == 0 {
|
||||
if wm = C.vips_image_copy_memory(watermark); wm == nil {
|
||||
return vipsError()
|
||||
}
|
||||
} else {
|
||||
wmW := maxInt(int(float64(imgW)*opts.Scale), 1)
|
||||
wmH := maxInt(int(float64(imgH)*opts.Scale), 1)
|
||||
|
||||
if wm, err = vipsResizeWatermark(wmW, wmH); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if opts.Replicate {
|
||||
if wm, err = vipsReplicateWatermark(imgW, imgH); err != nil {
|
||||
if err = vipsReplicate(&wm, imgW, imgH); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if wm, err = vipsEmbedWatermark(opts.Gravity, imgW, imgH, C.int(opts.OffsetX), C.int(opts.OffsetY)); err != nil {
|
||||
if err = vipsEmbed(&wm, opts.Gravity, imgW, imgH, C.int(opts.OffsetX), C.int(opts.OffsetY)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -103,6 +103,7 @@ type watermarkOptions struct {
|
||||
Gravity gravityType
|
||||
OffsetX int
|
||||
OffsetY int
|
||||
Scale float64
|
||||
}
|
||||
|
||||
type processingOptions struct {
|
||||
@ -431,6 +432,10 @@ func applyPresetOption(po *processingOptions, args []string) error {
|
||||
}
|
||||
|
||||
func applyWatermarkOption(po *processingOptions, args []string) error {
|
||||
if len(args) > 7 {
|
||||
return fmt.Errorf("Invalid watermark arguments: %v", args)
|
||||
}
|
||||
|
||||
if o, err := strconv.ParseFloat(args[0], 64); err == nil && o >= 0 && o <= 1 {
|
||||
po.Watermark.Enabled = o > 0
|
||||
po.Watermark.Opacity = o
|
||||
@ -438,7 +443,7 @@ func applyWatermarkOption(po *processingOptions, args []string) error {
|
||||
return fmt.Errorf("Invalid watermark opacity: %s", args[0])
|
||||
}
|
||||
|
||||
if len(args) > 1 {
|
||||
if len(args) > 1 && len(args[1]) > 0 {
|
||||
if args[1] == "re" {
|
||||
po.Watermark.Replicate = true
|
||||
} else if g, ok := gravityTypes[args[1]]; ok && g != gravityFocusPoint && g != gravitySmart {
|
||||
@ -448,7 +453,7 @@ func applyWatermarkOption(po *processingOptions, args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if len(args) > 2 {
|
||||
if len(args) > 2 && len(args[2]) > 0 {
|
||||
if x, err := strconv.Atoi(args[2]); err == nil {
|
||||
po.Watermark.OffsetX = x
|
||||
} else {
|
||||
@ -456,7 +461,7 @@ func applyWatermarkOption(po *processingOptions, args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if len(args) > 3 {
|
||||
if len(args) > 3 && len(args[3]) > 0 {
|
||||
if y, err := strconv.Atoi(args[3]); err == nil {
|
||||
po.Watermark.OffsetY = y
|
||||
} else {
|
||||
@ -464,6 +469,14 @@ func applyWatermarkOption(po *processingOptions, args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if len(args) > 4 && len(args[4]) > 0 {
|
||||
if s, err := strconv.ParseFloat(args[4], 64); err == nil && s >= 0 {
|
||||
po.Watermark.Scale = s
|
||||
} else {
|
||||
return fmt.Errorf("Invalid watermark scale: %s", args[4])
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user