rclone/vendor/github.com/yunify/qingstor-sdk-go/client/image/image.go
2017-09-30 08:10:50 +01:00

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
}