mirror of
https://github.com/imgproxy/imgproxy.git
synced 2024-11-24 08:12:38 +02:00
Merge branch 'version/3' into version/3-refactoring
This commit is contained in:
commit
29e4188cd3
@ -350,7 +350,7 @@ As an approximate guideline, use 0.5 sigma for 4 pixels/mm (display resolution),
|
||||
|
||||
Default: disabled
|
||||
|
||||
### Pixelate<img class='pro-badge' src='assets/pro.svg' alt='pro' /> :id=pixelate
|
||||
### Pixelate
|
||||
|
||||
```
|
||||
pixelate:%size
|
||||
|
@ -1,106 +0,0 @@
|
||||
# Generating the URL (Basic)
|
||||
|
||||
This guide describes the simple URL format that is easy to use but doesn't support the whole range of imgproxy features. This URL format is mostly supported for backwards compatibility with imgproxy 1.x. Please read our [Generating the URL (Advanced)](generating_the_url_advanced.md) guide to learn about the advanced URL format.
|
||||
|
||||
## Format definition
|
||||
|
||||
The basic URL should contain the signature, resize parameters, and source URL, like this:
|
||||
|
||||
```
|
||||
/%signature/%resizing_type/%width/%height/%gravity/%enlarge/plain/%source_url@%extension
|
||||
/%signature/%resizing_type/%width/%height/%gravity/%enlarge/%encoded_source_url.%extension
|
||||
```
|
||||
|
||||
Check out the [example](#example) at the end of this guide.
|
||||
|
||||
### Signature
|
||||
|
||||
Signature protects your URL from being modified by an attacker. It is highly recommended to sign imgproxy URLs in a production environment.
|
||||
|
||||
Once you set up your [URL signature](configuration.md#url-signature), check out the [Signing the URL](signing_the_url.md) guide to learn about how to sign your URLs. Otherwise, use any string here.
|
||||
|
||||
### Resizing types
|
||||
|
||||
imgproxy supports the following resizing types:
|
||||
|
||||
* `fit`: resizes the image while keeping aspect ratio to fit given size;
|
||||
* `fill`: resizes the image while keeping aspect ratio to fill given size and cropping projecting parts;
|
||||
* `auto`: if both source and resulting dimensions have the same orientation (portrait or landscape), imgproxy will use `fill`. Otherwise, it will use `fit`.
|
||||
|
||||
### Width and height
|
||||
|
||||
Width and height parameters define the size of the resulting image in pixels. Depending on the resizing type applied, the dimensions may differ from the requested ones.
|
||||
|
||||
### Gravity
|
||||
|
||||
When imgproxy needs to cut some parts of the image, it is guided by the gravity. The following values are supported:
|
||||
|
||||
* `no`: north (top edge);
|
||||
* `so`: south (bottom edge);
|
||||
* `ea`: east (right edge);
|
||||
* `we`: west (left edge);
|
||||
* `noea`: north-east (top-right corner);
|
||||
* `nowe`: north-west (top-left corner);
|
||||
* `soea`: south-east (bottom-right corner);
|
||||
* `sowe`: south-west (bottom-left corner);
|
||||
* `ce`: center;
|
||||
* `sm`: smart. `libvips` detects the most "interesting" section of the image and considers it as the center of the resulting image;
|
||||
* `fp:%x:%y` - focus point. `x` and `y` are floating point numbers between 0 and 1 that describe the coordinates of the center of the resulting image. Treat 0 and 1 as right/left for `x` and top/bottom for `y`.
|
||||
|
||||
### Enlarge
|
||||
|
||||
When set to `1`, `t` or `true`, imgproxy will enlarge the image if it is smaller than the given size.
|
||||
|
||||
### Source URL
|
||||
|
||||
There are two ways to specify source url:
|
||||
|
||||
#### Plain
|
||||
|
||||
The source URL can be provided as is, prepended by `/plain/` part:
|
||||
|
||||
```
|
||||
/plain/http://example.com/images/curiosity.jpg
|
||||
```
|
||||
|
||||
**📝Note:** If the source URL contains query string or `@`, you need to escape it.
|
||||
|
||||
When using plain source URL, you can specify the [extension](#extension) after `@`:
|
||||
|
||||
```
|
||||
/plain/http://example.com/images/curiosity.jpg@png
|
||||
```
|
||||
|
||||
#### Base64 encoded
|
||||
|
||||
The source URL can be encoded with URL-safe Base64. The encoded URL can be split with `/` for your needs:
|
||||
|
||||
```
|
||||
/aHR0cDovL2V4YW1w/bGUuY29tL2ltYWdl/cy9jdXJpb3NpdHku/anBn
|
||||
```
|
||||
|
||||
When using encoded source URL, you can specify the [extension](#extension) after `.`:
|
||||
|
||||
```
|
||||
/aHR0cDovL2V4YW1w/bGUuY29tL2ltYWdl/cy9jdXJpb3NpdHku/anBn.png
|
||||
```
|
||||
|
||||
### Extension
|
||||
|
||||
Extension specifies the format of the resulting image. Read about image formats support [here](image_formats_support.md).
|
||||
|
||||
The extension part can be omitted. In this case, imgproxy will use source image format as resulting one. If source image format is not supported as resulting, imgproxy will use `jpg`. You also can [enable WebP support detection](configuration.md#webp-support-detection) to use it as default resulting format when possible.
|
||||
|
||||
## Example
|
||||
|
||||
Signed imgproxy URL that resizes `http://example.com/images/curiosity.jpg` to fill `300x400` area with smart gravity without enlarging, and converts the image to `png`:
|
||||
|
||||
```
|
||||
http://imgproxy.example.com/AfrOrF3gWeDA6VOlDG4TzxMv39O7MXnF4CXpKUwGqRM/fill/300/400/sm/0/plain/http://example.com/images/curiosity.jpg@png
|
||||
```
|
||||
|
||||
The same URL with Base64-encoded source URL will look like this:
|
||||
|
||||
```
|
||||
http://imgproxy.example.com/AfrOrF3gWeDA6VOlDG4TzxMv39O7MXnF4CXpKUwGqRM/fill/300/400/sm/0/aHR0cDovL2V4YW1w/bGUuY29tL2ltYWdl/cy9jdXJpb3NpdHku/anBn.png
|
||||
```
|
@ -84,6 +84,7 @@ type ProcessingOptions struct {
|
||||
Background vips.Color
|
||||
Blur float32
|
||||
Sharpen float32
|
||||
Pixelate int
|
||||
StripMetadata bool
|
||||
StripColorProfile bool
|
||||
AutoRotate bool
|
||||
@ -603,6 +604,20 @@ func applySharpenOption(po *ProcessingOptions, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyPixelateOption(po *ProcessingOptions, args []string) error {
|
||||
if len(args) > 1 {
|
||||
return fmt.Errorf("Invalid pixelate arguments: %v", args)
|
||||
}
|
||||
|
||||
if p, err := strconv.Atoi(args[0]); err == nil && p >= 0 {
|
||||
po.Pixelate = p
|
||||
} else {
|
||||
return fmt.Errorf("Invalid pixelate: %s", args[0])
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyPresetOption(po *ProcessingOptions, args []string) error {
|
||||
for _, preset := range args {
|
||||
if p, ok := presets[preset]; ok {
|
||||
@ -806,6 +821,8 @@ func applyURLOption(po *ProcessingOptions, name string, args []string) error {
|
||||
return applyBlurOption(po, args)
|
||||
case "sharpen", "sh":
|
||||
return applySharpenOption(po, args)
|
||||
case "pixelate", "pix":
|
||||
return applyPixelateOption(po, args)
|
||||
case "watermark", "wm":
|
||||
return applyWatermarkOption(po, args)
|
||||
case "strip_metadata", "sm":
|
||||
|
@ -2,12 +2,13 @@ package processing
|
||||
|
||||
import (
|
||||
"github.com/imgproxy/imgproxy/v2/imagedata"
|
||||
"github.com/imgproxy/imgproxy/v2/imath"
|
||||
"github.com/imgproxy/imgproxy/v2/options"
|
||||
"github.com/imgproxy/imgproxy/v2/vips"
|
||||
)
|
||||
|
||||
func applyFilters(pctx *pipelineContext, img *vips.Image, po *options.ProcessingOptions, imgdata *imagedata.ImageData) error {
|
||||
if po.Blur == 0 && po.Sharpen == 0 {
|
||||
if po.Blur == 0 && po.Sharpen == 0 && po.Pixelate < 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -36,6 +37,13 @@ func applyFilters(pctx *pipelineContext, img *vips.Image, po *options.Processing
|
||||
}
|
||||
}
|
||||
|
||||
if po.Pixelate > 1 {
|
||||
pixels := imath.Min(po.Pixelate, imath.Min(img.Width(), img.Height()))
|
||||
if err := img.Pixelate(pixels); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := img.Unpremultiply(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
49
vips/vips.c
49
vips/vips.c
@ -209,6 +209,55 @@ vips_resize_go(VipsImage *in, VipsImage **out, double wscale, double hscale) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
vips_pixelate(VipsImage *in, VipsImage **out, int pixels) {
|
||||
VipsImage *base = vips_image_new();
|
||||
VipsImage **t = (VipsImage **) vips_object_local_array(VIPS_OBJECT(base), 3);
|
||||
|
||||
int w, h, tw, th;
|
||||
|
||||
w = in->Xsize;
|
||||
h = in->Ysize;
|
||||
|
||||
tw = (int)((double)(w + pixels - 1) / pixels) * pixels;
|
||||
th = (int)((double)(h + pixels - 1) / pixels) * pixels;
|
||||
|
||||
if (tw > w || th > h) {
|
||||
if (vips_embed(in, &t[0], 0, 0, tw, th, "extend", VIPS_EXTEND_COPY, NULL)) {
|
||||
clear_image(&base);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (vips_copy(in, &t[0], NULL)) {
|
||||
clear_image(&base);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
vips_shrink(t[0], &t[1], pixels, pixels, NULL) ||
|
||||
vips_zoom(t[1], &t[2], pixels, pixels, NULL)
|
||||
) {
|
||||
clear_image(&base);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (tw > w || th > h) {
|
||||
if (vips_extract_area(t[2], out, 0, 0, w, h, NULL)) {
|
||||
clear_image(&base);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (vips_copy(t[2], out, NULL)) {
|
||||
clear_image(&base);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
clear_image(&base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
vips_icc_is_srgb_iec61966(VipsImage *in) {
|
||||
const void *data;
|
||||
|
12
vips/vips.go
12
vips/vips.go
@ -436,6 +436,18 @@ func (img *Image) Resize(wscale, hscale float64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (img *Image) Pixelate(pixels int) error {
|
||||
var tmp *C.VipsImage
|
||||
|
||||
if C.vips_pixelate(img.VipsImage, &tmp, C.int(pixels)) != 0 {
|
||||
return Error()
|
||||
}
|
||||
|
||||
C.swap_and_clear(&img.VipsImage, tmp)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (img *Image) Orientation() C.int {
|
||||
return C.vips_get_orientation(img.VipsImage)
|
||||
}
|
||||
|
@ -44,6 +44,8 @@ int vips_rad2float_go(VipsImage *in, VipsImage **out);
|
||||
|
||||
int vips_resize_go(VipsImage *in, VipsImage **out, double wscale, double hscale);
|
||||
|
||||
int vips_pixelate(VipsImage *in, VipsImage **out, int pixels);
|
||||
|
||||
int vips_icc_is_srgb_iec61966(VipsImage *in);
|
||||
int vips_has_embedded_icc(VipsImage *in);
|
||||
int vips_icc_import_go(VipsImage *in, VipsImage **out);
|
||||
|
Loading…
Reference in New Issue
Block a user