mirror of
https://github.com/rclone/rclone.git
synced 2024-12-02 13:25:51 +01:00
260 lines
6.0 KiB
Go
260 lines
6.0 KiB
Go
package image
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
|
|
"github.com/yunify/qingstor-sdk-go/service"
|
|
)
|
|
|
|
const (
|
|
// ActionSep is separator of action.
|
|
ActionSep = ":"
|
|
|
|
// OPSep is separator of operation.
|
|
OPSep = "|"
|
|
|
|
// KVSep is separator of Key-Value.
|
|
KVSep = "_"
|
|
|
|
//KVPairSep is separator of args.
|
|
KVPairSep = ","
|
|
)
|
|
|
|
const (
|
|
// InfoOperation is string of info operation.
|
|
InfoOperation string = "info"
|
|
|
|
// CropOperation is string of crop operation.
|
|
CropOperation string = "crop"
|
|
|
|
// FormatOperation is string of format operation.
|
|
FormatOperation string = "format"
|
|
|
|
// ResizeOperation is string of resize operation.
|
|
ResizeOperation string = "resize"
|
|
|
|
// RotateOperation is string of rotate operation.
|
|
RotateOperation string = "rotate"
|
|
|
|
// WaterMarkOperation is string of watermark operation.
|
|
WaterMarkOperation string = "watermark"
|
|
|
|
// WaterMarkImageOperation is string of watermark image operation.
|
|
WaterMarkImageOperation string = "watermark_image"
|
|
)
|
|
|
|
// ResizeMode is the type of resize mode.
|
|
type ResizeMode int
|
|
|
|
const (
|
|
// ResizeFixed resizes image to fix width and height.
|
|
ResizeFixed ResizeMode = iota
|
|
|
|
// ResizeForce resizes image to force witdth and height.
|
|
ResizeForce
|
|
|
|
// ResizeThumbnail resizes image to thumbnail width and height.
|
|
ResizeThumbnail
|
|
)
|
|
|
|
// CropGravity is the type of crop gravity.
|
|
type CropGravity int
|
|
|
|
const (
|
|
|
|
// CropCenter crops image to center width and height.
|
|
CropCenter CropGravity = iota
|
|
|
|
// CropNorth crops image to north width and height.
|
|
CropNorth
|
|
|
|
// CropEast crops image to east width and height.
|
|
CropEast
|
|
|
|
// CropSouth crops image to south width and height.
|
|
CropSouth
|
|
|
|
// CropWest crops image to west width and height.
|
|
CropWest
|
|
|
|
// CropNorthWest crops image to north west width and height.
|
|
CropNorthWest
|
|
|
|
// CropNorthEast crops image to north east width and height.
|
|
CropNorthEast
|
|
|
|
// CropSouthWest crops image to south west width and height.
|
|
CropSouthWest
|
|
|
|
// CropSouthEast crops image to south east width and height.
|
|
CropSouthEast
|
|
|
|
// CropAuto crops image to auto width and height.
|
|
CropAuto
|
|
)
|
|
|
|
// Image is struct of Image process.
|
|
type Image struct {
|
|
key *string
|
|
bucket *service.Bucket
|
|
input *service.ImageProcessInput
|
|
}
|
|
|
|
// Init initializes an image to process.
|
|
func Init(bucket *service.Bucket, objectKey string) *Image {
|
|
return &Image{
|
|
key: &objectKey,
|
|
bucket: bucket,
|
|
input: &service.ImageProcessInput{},
|
|
}
|
|
}
|
|
|
|
// Info gets the information of the image.
|
|
func (image *Image) Info() *Image {
|
|
return image.setActionParam(InfoOperation, nil)
|
|
}
|
|
|
|
// RotateParam is param of the rotate operation.
|
|
type RotateParam struct {
|
|
Angle int `schema:"a"`
|
|
}
|
|
|
|
// Rotate image.
|
|
func (image *Image) Rotate(param *RotateParam) *Image {
|
|
return image.setActionParam(RotateOperation, param)
|
|
}
|
|
|
|
// ResizeParam is param of the resize operation.
|
|
type ResizeParam struct {
|
|
Width int `schema:"w,omitempty"`
|
|
Height int `schema:"h,omitempty"`
|
|
Mode ResizeMode `schema:"m"`
|
|
}
|
|
|
|
// Resize image.
|
|
func (image *Image) Resize(param *ResizeParam) *Image {
|
|
return image.setActionParam(ResizeOperation, param)
|
|
}
|
|
|
|
// CropParam is param of the crop operation.
|
|
type CropParam struct {
|
|
Width int `schema:"w,omitempty"`
|
|
Height int `schema:"h,omitempty"`
|
|
Gravity CropGravity `schema:"g"`
|
|
}
|
|
|
|
// Crop image.
|
|
func (image *Image) Crop(param *CropParam) *Image {
|
|
return image.setActionParam(CropOperation, param)
|
|
}
|
|
|
|
// FormatParam is param of the format operation.
|
|
type FormatParam struct {
|
|
Type string `schema:"t"`
|
|
}
|
|
|
|
// Format image.
|
|
func (image *Image) Format(param *FormatParam) *Image {
|
|
return image.setActionParam(FormatOperation, param)
|
|
}
|
|
|
|
// WaterMarkParam is param of the wartermark operation.
|
|
type WaterMarkParam struct {
|
|
Dpi int `schema:"d,omitempty"`
|
|
Opacity float64 `schema:"p,omitempty"`
|
|
Text string `schema:"t"`
|
|
Color string `schema:"c"`
|
|
}
|
|
|
|
// WaterMark is operation of watermark text content.
|
|
func (image *Image) WaterMark(param *WaterMarkParam) *Image {
|
|
return image.setActionParam(WaterMarkOperation, param)
|
|
}
|
|
|
|
// WaterMarkImageParam is param of the waterMark image operation
|
|
type WaterMarkImageParam struct {
|
|
Left int `schema:"l"`
|
|
Top int `schema:"t"`
|
|
Opacity float64 `schema:"p,omitempty"`
|
|
URL string `schema:"u"`
|
|
}
|
|
|
|
// WaterMarkImage is operation of watermark image.
|
|
func (image *Image) WaterMarkImage(param *WaterMarkImageParam) *Image {
|
|
return image.setActionParam(WaterMarkImageOperation, param)
|
|
}
|
|
|
|
// Process does Image process.
|
|
func (image *Image) Process() (*service.ImageProcessOutput, error) {
|
|
defer func(input *service.ImageProcessInput) {
|
|
input.Action = nil
|
|
}(image.input)
|
|
return image.bucket.ImageProcess(*image.key, image.input)
|
|
}
|
|
|
|
func (image *Image) setActionParam(operation string, param interface{}) *Image {
|
|
uri := operation
|
|
if param != nil {
|
|
uri = fmt.Sprintf("%s%s%s", uri, ActionSep, buildOptParamStr(param))
|
|
}
|
|
if image.input.Action != nil {
|
|
uri = fmt.Sprintf("%s%s%s", *image.input.Action, OPSep, uri)
|
|
}
|
|
image.input.Action = &uri
|
|
return image
|
|
}
|
|
|
|
func buildOptParamStr(param interface{}) string {
|
|
v := reflect.ValueOf(param).Elem()
|
|
var kvPairs []string
|
|
|
|
for i := 0; i < v.NumField(); i++ {
|
|
vf := v.Field(i)
|
|
tf := v.Type().Field(i)
|
|
key := tf.Tag.Get("schema")
|
|
value := vf.Interface()
|
|
tagValues := strings.Split(key, ",")
|
|
if isEmptyValue(vf) &&
|
|
len(tagValues) == 2 &&
|
|
tagValues[1] == "omitempty" {
|
|
continue
|
|
}
|
|
key = tagValues[0]
|
|
kvPairs = append(kvPairs, fmt.Sprintf("%v%s%v", key, KVSep, value))
|
|
}
|
|
return strings.Join(kvPairs, KVPairSep)
|
|
}
|
|
|
|
func isEmptyValue(v reflect.Value) bool {
|
|
switch v.Kind() {
|
|
case reflect.Array,
|
|
reflect.Map,
|
|
reflect.Slice,
|
|
reflect.String:
|
|
return v.Len() == 0
|
|
case reflect.Bool:
|
|
return !v.Bool()
|
|
case reflect.Int,
|
|
reflect.Int8,
|
|
reflect.Int16,
|
|
reflect.Int32,
|
|
reflect.Int64:
|
|
return v.Int() == 0
|
|
case reflect.Uint,
|
|
reflect.Uint8,
|
|
reflect.Uint16,
|
|
reflect.Uint32,
|
|
reflect.Uint64,
|
|
reflect.Uintptr:
|
|
return v.Uint() == 0
|
|
case reflect.Float32,
|
|
reflect.Float64:
|
|
return v.Float() == 0
|
|
case reflect.Ptr:
|
|
return v.IsNil()
|
|
}
|
|
return false
|
|
}
|