mirror of
https://github.com/imgproxy/imgproxy.git
synced 2024-11-24 08:12:38 +02:00
rotate processing option
This commit is contained in:
parent
6da8885605
commit
e48c557fc4
@ -7,6 +7,7 @@
|
||||
- `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_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.
|
||||
- (pro) Remove Adobe Illustrator garbage from SVGs.
|
||||
|
||||
### Changed
|
||||
|
@ -208,6 +208,19 @@ Removes surrounding background.
|
||||
|
||||
**📝Note:** Trimming of animated images is not supported.
|
||||
|
||||
#### Rotate
|
||||
|
||||
```
|
||||
rotate:%angle
|
||||
rot:%angle
|
||||
```
|
||||
|
||||
Rotates the image on the specified angle. The orientation from the image metadata is applied before the rotation unless autorotation is disabled.
|
||||
|
||||
**📝Note:** Only 0/90/180/270/etc degrees angles are supported.
|
||||
|
||||
Default: 0.
|
||||
|
||||
#### Quality
|
||||
|
||||
```
|
||||
|
45
process.go
45
process.go
@ -34,34 +34,33 @@ func imageTypeGoodForWeb(imgtype imageType) bool {
|
||||
imgtype != imageTypeBMP
|
||||
}
|
||||
|
||||
func extractMeta(img *vipsImage, useOrientation bool) (int, int, int, bool) {
|
||||
func extractMeta(img *vipsImage, baseAngle int, useOrientation bool) (int, int, int, bool) {
|
||||
width := img.Width()
|
||||
height := img.Height()
|
||||
|
||||
angle := vipsAngleD0
|
||||
angle := 0
|
||||
flip := false
|
||||
|
||||
if !useOrientation {
|
||||
return width, height, angle, flip
|
||||
if useOrientation {
|
||||
orientation := img.Orientation()
|
||||
|
||||
if orientation == 3 || orientation == 4 {
|
||||
angle = 180
|
||||
}
|
||||
if orientation == 5 || orientation == 6 {
|
||||
angle = 90
|
||||
}
|
||||
if orientation == 7 || orientation == 8 {
|
||||
angle = 270
|
||||
}
|
||||
if orientation == 2 || orientation == 4 || orientation == 5 || orientation == 7 {
|
||||
flip = true
|
||||
}
|
||||
}
|
||||
|
||||
orientation := img.Orientation()
|
||||
|
||||
if orientation >= 5 && orientation <= 8 {
|
||||
if (angle+baseAngle)%180 != 0 {
|
||||
width, height = height, width
|
||||
}
|
||||
if orientation == 3 || orientation == 4 {
|
||||
angle = vipsAngleD180
|
||||
}
|
||||
if orientation == 5 || orientation == 6 {
|
||||
angle = vipsAngleD90
|
||||
}
|
||||
if orientation == 7 || orientation == 8 {
|
||||
angle = vipsAngleD270
|
||||
}
|
||||
if orientation == 2 || orientation == 4 || orientation == 5 || orientation == 7 {
|
||||
flip = true
|
||||
}
|
||||
|
||||
return width, height, angle, flip
|
||||
}
|
||||
@ -325,7 +324,7 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
|
||||
trimmed = true
|
||||
}
|
||||
|
||||
srcWidth, srcHeight, angle, flip := extractMeta(img, po.AutoRotate)
|
||||
srcWidth, srcHeight, angle, flip := extractMeta(img, po.Rotate, po.AutoRotate)
|
||||
cropWidth, cropHeight := po.Crop.Width, po.Crop.Height
|
||||
|
||||
cropGravity := po.Crop.Gravity
|
||||
@ -356,7 +355,7 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
|
||||
}
|
||||
|
||||
// Update scale after scale-on-load
|
||||
newWidth, newHeight, _, _ := extractMeta(img, po.AutoRotate)
|
||||
newWidth, newHeight, _, _ := extractMeta(img, po.Rotate, po.AutoRotate)
|
||||
if srcWidth > srcHeight {
|
||||
scale = float64(srcWidth) * scale / float64(newWidth)
|
||||
} else {
|
||||
@ -413,6 +412,10 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
|
||||
}
|
||||
}
|
||||
|
||||
if err = img.Rotate(po.Rotate); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dprWidth := scaleInt(po.Width, po.Dpr)
|
||||
dprHeight := scaleInt(po.Height, po.Dpr)
|
||||
|
||||
|
@ -136,6 +136,7 @@ type processingOptions struct {
|
||||
Crop cropOptions
|
||||
Padding paddingOptions
|
||||
Trim trimOptions
|
||||
Rotate int
|
||||
Format imageType
|
||||
Quality int
|
||||
MaxBytes int
|
||||
@ -222,6 +223,7 @@ func newProcessingOptions() *processingOptions {
|
||||
Extend: extendOptions{Enabled: false, Gravity: gravityOptions{Type: gravityCenter}},
|
||||
Padding: paddingOptions{Enabled: false},
|
||||
Trim: trimOptions{Enabled: false, Threshold: 10, Smart: true},
|
||||
Rotate: 0,
|
||||
Quality: 0,
|
||||
MaxBytes: 0,
|
||||
Format: imageTypeUnknown,
|
||||
@ -664,6 +666,20 @@ func applyTrimOption(po *processingOptions, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyRotateOption(po *processingOptions, args []string) error {
|
||||
if len(args) > 1 {
|
||||
return fmt.Errorf("Invalid rotate arguments: %v", args)
|
||||
}
|
||||
|
||||
if r, err := strconv.Atoi(args[0]); err == nil && r%90 == 0 {
|
||||
po.Rotate = r
|
||||
} else {
|
||||
return fmt.Errorf("Invalid rotation angle: %s", args[0])
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyQualityOption(po *processingOptions, args []string) error {
|
||||
if len(args) > 1 {
|
||||
return fmt.Errorf("Invalid quality arguments: %v", args)
|
||||
@ -924,6 +940,8 @@ func applyProcessingOption(po *processingOptions, name string, args []string) er
|
||||
return applyCropOption(po, args)
|
||||
case "trim", "t":
|
||||
return applyTrimOption(po, args)
|
||||
case "rotate", "rot":
|
||||
return applyRotateOption(po, args)
|
||||
case "padding", "pd":
|
||||
return applyPaddingOption(po, args)
|
||||
case "quality", "q":
|
||||
|
11
vips.go
11
vips.go
@ -38,13 +38,6 @@ var vipsConf struct {
|
||||
WatermarkOpacity C.double
|
||||
}
|
||||
|
||||
const (
|
||||
vipsAngleD0 = C.VIPS_ANGLE_D0
|
||||
vipsAngleD90 = C.VIPS_ANGLE_D90
|
||||
vipsAngleD180 = C.VIPS_ANGLE_D180
|
||||
vipsAngleD270 = C.VIPS_ANGLE_D270
|
||||
)
|
||||
|
||||
func initVips() error {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
@ -392,7 +385,9 @@ func (img *vipsImage) Orientation() C.int {
|
||||
func (img *vipsImage) Rotate(angle int) error {
|
||||
var tmp *C.VipsImage
|
||||
|
||||
if C.vips_rot_go(img.VipsImage, &tmp, C.VipsAngle(angle)) != 0 {
|
||||
vipsAngle := (angle / 90) % 4
|
||||
|
||||
if C.vips_rot_go(img.VipsImage, &tmp, C.VipsAngle(vipsAngle)) != 0 {
|
||||
return vipsError()
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user