mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-10-09 19:52:30 +02:00
IMGPROXY_AUTO_ROTATE config and auto_rotate processing option
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
- Azure Blob Storage support.
|
- Azure Blob Storage support.
|
||||||
- `IMGPROXY_STRIP_COLOR_PROFILE` config and [strip_color_profile](https://docs.imgproxy.net/#/generating_the_url_advanced?id=strip-color-profile) processing option.
|
- `IMGPROXY_STRIP_COLOR_PROFILE` config and [strip_color_profile](https://docs.imgproxy.net/#/generating_the_url_advanced?id=strip-color-profile) processing option.
|
||||||
- `IMGPROXY_FORMAT_QUALITY` config.
|
- `IMGPROXY_FORMAT_QUALITY` config.
|
||||||
|
- `IMGPROXY_AUTO_ROTATE` config and [auto_rotate](https://docs.imgproxy.net/#/generating_the_url_advanced?id=auto-rotate) processing option.
|
||||||
- (pro) Remove Adobe Illustrator garbage from SVGs.
|
- (pro) Remove Adobe Illustrator garbage from SVGs.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
@@ -229,6 +229,7 @@ type config struct {
|
|||||||
GZipCompression int
|
GZipCompression int
|
||||||
StripMetadata bool
|
StripMetadata bool
|
||||||
StripColorProfile bool
|
StripColorProfile bool
|
||||||
|
AutoRotate bool
|
||||||
|
|
||||||
EnableWebpDetection bool
|
EnableWebpDetection bool
|
||||||
EnforceWebp bool
|
EnforceWebp bool
|
||||||
@@ -323,6 +324,7 @@ var conf = config{
|
|||||||
FormatQuality: map[imageType]int{imageTypeAVIF: 50},
|
FormatQuality: map[imageType]int{imageTypeAVIF: 50},
|
||||||
StripMetadata: true,
|
StripMetadata: true,
|
||||||
StripColorProfile: true,
|
StripColorProfile: true,
|
||||||
|
AutoRotate: true,
|
||||||
UserAgent: fmt.Sprintf("imgproxy/%s", version),
|
UserAgent: fmt.Sprintf("imgproxy/%s", version),
|
||||||
Presets: make(presets),
|
Presets: make(presets),
|
||||||
WatermarkOpacity: 1,
|
WatermarkOpacity: 1,
|
||||||
@@ -383,6 +385,7 @@ func configure() error {
|
|||||||
intEnvConfig(&conf.GZipCompression, "IMGPROXY_GZIP_COMPRESSION")
|
intEnvConfig(&conf.GZipCompression, "IMGPROXY_GZIP_COMPRESSION")
|
||||||
boolEnvConfig(&conf.StripMetadata, "IMGPROXY_STRIP_METADATA")
|
boolEnvConfig(&conf.StripMetadata, "IMGPROXY_STRIP_METADATA")
|
||||||
boolEnvConfig(&conf.StripColorProfile, "IMGPROXY_STRIP_COLOR_PROFILE")
|
boolEnvConfig(&conf.StripColorProfile, "IMGPROXY_STRIP_COLOR_PROFILE")
|
||||||
|
boolEnvConfig(&conf.AutoRotate, "IMGPROXY_AUTO_ROTATE")
|
||||||
|
|
||||||
boolEnvConfig(&conf.EnableWebpDetection, "IMGPROXY_ENABLE_WEBP_DETECTION")
|
boolEnvConfig(&conf.EnableWebpDetection, "IMGPROXY_ENABLE_WEBP_DETECTION")
|
||||||
boolEnvConfig(&conf.EnforceWebp, "IMGPROXY_ENFORCE_WEBP")
|
boolEnvConfig(&conf.EnforceWebp, "IMGPROXY_ENFORCE_WEBP")
|
||||||
|
@@ -325,3 +325,4 @@ imgproxy can send logs to syslog, but this feature is disabled by default. To en
|
|||||||
* `IMGPROXY_DISABLE_SHRINK_ON_LOAD`: when `true`, disables shrink-on-load for JPEG and WebP. Allows to process the whole image in linear colorspace but dramatically slows down resizing and increases memory usage when working with large images.
|
* `IMGPROXY_DISABLE_SHRINK_ON_LOAD`: when `true`, disables shrink-on-load for JPEG and WebP. Allows to process the whole image in linear colorspace but dramatically slows down resizing and increases memory usage when working with large images.
|
||||||
* `IMGPROXY_STRIP_METADATA`: when `true`, imgproxy will strip all metadata (EXIF, IPTC, etc.) from JPEG and WebP output images. Default: `true`.
|
* `IMGPROXY_STRIP_METADATA`: when `true`, imgproxy will strip all metadata (EXIF, IPTC, etc.) from JPEG and WebP output images. Default: `true`.
|
||||||
* `IMGPROXY_STRIP_COLOR_PROFILE`: when `true`, imgproxy will transform the embedded color profile (ICC) to sRGB and remove it from the image. Otherwise, imgproxy will try to keep it as is. Default: `true`.
|
* `IMGPROXY_STRIP_COLOR_PROFILE`: when `true`, imgproxy will transform the embedded color profile (ICC) to sRGB and remove it from the image. Otherwise, imgproxy will try to keep it as is. Default: `true`.
|
||||||
|
* `IMGPROXY_AUTO_ROTATE`: when `true`, imgproxy will auto rotate images based on the EXIF Orientation parameter (if available in the image meta data). The orientation tag will be removed from the image anyway. Default: `true`.
|
||||||
|
@@ -486,6 +486,15 @@ scp:%strip_color_profile
|
|||||||
|
|
||||||
When set to `1`, `t` or `true`, imgproxy will transform the embedded color profile (ICC) to sRGB and remove it from the image. Otherwise, imgproxy will try to keep it as is. Normally this is controlled by the [IMGPROXY_STRIP_COLOR_PROFILE](configuration.md#miscellaneous) configuration but this procesing option allows the configuration to be set for each request.
|
When set to `1`, `t` or `true`, imgproxy will transform the embedded color profile (ICC) to sRGB and remove it from the image. Otherwise, imgproxy will try to keep it as is. Normally this is controlled by the [IMGPROXY_STRIP_COLOR_PROFILE](configuration.md#miscellaneous) configuration but this procesing option allows the configuration to be set for each request.
|
||||||
|
|
||||||
|
#### Auto Rotate
|
||||||
|
|
||||||
|
```
|
||||||
|
auto_rotate:%auto_rotate
|
||||||
|
ar:%auto_rotate
|
||||||
|
```
|
||||||
|
|
||||||
|
When set to `1`, `t` or `true`, imgproxy will automatically rotate images based onon the EXIF Orientation parameter (if available in the image meta data). The orientation tag will be removed from the image anyway. Normally this is controlled by the [IMGPROXY_AUTO_ROTATE](configuration.md#miscellaneous) configuration but this procesing option allows the configuration to be set for each request.
|
||||||
|
|
||||||
#### Filename
|
#### Filename
|
||||||
|
|
||||||
```
|
```
|
||||||
|
16
process.go
16
process.go
@@ -34,13 +34,17 @@ func imageTypeGoodForWeb(imgtype imageType) bool {
|
|||||||
imgtype != imageTypeBMP
|
imgtype != imageTypeBMP
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractMeta(img *vipsImage) (int, int, int, bool) {
|
func extractMeta(img *vipsImage, useOrientation bool) (int, int, int, bool) {
|
||||||
width := img.Width()
|
width := img.Width()
|
||||||
height := img.Height()
|
height := img.Height()
|
||||||
|
|
||||||
angle := vipsAngleD0
|
angle := vipsAngleD0
|
||||||
flip := false
|
flip := false
|
||||||
|
|
||||||
|
if !useOrientation {
|
||||||
|
return width, height, angle, flip
|
||||||
|
}
|
||||||
|
|
||||||
orientation := img.Orientation()
|
orientation := img.Orientation()
|
||||||
|
|
||||||
if orientation >= 5 && orientation <= 8 {
|
if orientation >= 5 && orientation <= 8 {
|
||||||
@@ -321,7 +325,7 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
|
|||||||
trimmed = true
|
trimmed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
srcWidth, srcHeight, angle, flip := extractMeta(img)
|
srcWidth, srcHeight, angle, flip := extractMeta(img, po.AutoRotate)
|
||||||
cropWidth, cropHeight := po.Crop.Width, po.Crop.Height
|
cropWidth, cropHeight := po.Crop.Width, po.Crop.Height
|
||||||
|
|
||||||
cropGravity := po.Crop.Gravity
|
cropGravity := po.Crop.Gravity
|
||||||
@@ -352,7 +356,7 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update scale after scale-on-load
|
// Update scale after scale-on-load
|
||||||
newWidth, newHeight, _, _ := extractMeta(img)
|
newWidth, newHeight, _, _ := extractMeta(img, po.AutoRotate)
|
||||||
if srcWidth > srcHeight {
|
if srcWidth > srcHeight {
|
||||||
scale = float64(srcWidth) * scale / float64(newWidth)
|
scale = float64(srcWidth) * scale / float64(newWidth)
|
||||||
} else {
|
} else {
|
||||||
@@ -399,10 +403,8 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if angle != vipsAngleD0 {
|
if err = img.Rotate(angle); err != nil {
|
||||||
if err = img.Rotate(angle); err != nil {
|
return err
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if flip {
|
if flip {
|
||||||
|
@@ -145,6 +145,7 @@ type processingOptions struct {
|
|||||||
Sharpen float32
|
Sharpen float32
|
||||||
StripMetadata bool
|
StripMetadata bool
|
||||||
StripColorProfile bool
|
StripColorProfile bool
|
||||||
|
AutoRotate bool
|
||||||
|
|
||||||
CacheBuster string
|
CacheBuster string
|
||||||
|
|
||||||
@@ -231,6 +232,7 @@ func newProcessingOptions() *processingOptions {
|
|||||||
Watermark: watermarkOptions{Opacity: 1, Replicate: false, Gravity: gravityOptions{Type: gravityCenter}},
|
Watermark: watermarkOptions{Opacity: 1, Replicate: false, Gravity: gravityOptions{Type: gravityCenter}},
|
||||||
StripMetadata: conf.StripMetadata,
|
StripMetadata: conf.StripMetadata,
|
||||||
StripColorProfile: conf.StripColorProfile,
|
StripColorProfile: conf.StripColorProfile,
|
||||||
|
AutoRotate: conf.AutoRotate,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -886,6 +888,16 @@ func applyStripColorProfileOption(po *processingOptions, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func applyAutoRotateOption(po *processingOptions, args []string) error {
|
||||||
|
if len(args) > 1 {
|
||||||
|
return fmt.Errorf("Invalid auto rotate arguments: %v", args)
|
||||||
|
}
|
||||||
|
|
||||||
|
po.AutoRotate = parseBoolOption(args[0])
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func applyProcessingOption(po *processingOptions, name string, args []string) error {
|
func applyProcessingOption(po *processingOptions, name string, args []string) error {
|
||||||
switch name {
|
switch name {
|
||||||
case "format", "f", "ext":
|
case "format", "f", "ext":
|
||||||
@@ -934,6 +946,8 @@ func applyProcessingOption(po *processingOptions, name string, args []string) er
|
|||||||
return applyStripMetadataOption(po, args)
|
return applyStripMetadataOption(po, args)
|
||||||
case "strip_color_profile", "scp":
|
case "strip_color_profile", "scp":
|
||||||
return applyStripColorProfileOption(po, args)
|
return applyStripColorProfileOption(po, args)
|
||||||
|
case "auto_rotate", "ar":
|
||||||
|
return applyAutoRotateOption(po, args)
|
||||||
case "filename", "fn":
|
case "filename", "fn":
|
||||||
return applyFilenameOption(po, args)
|
return applyFilenameOption(po, args)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user