Skip to content

Commit

Permalink
feat(gif): support gif process
Browse files Browse the repository at this point in the history
  • Loading branch information
zhoukk committed May 11, 2019
1 parent 5d124f7 commit c931e3c
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 47 deletions.
2 changes: 1 addition & 1 deletion context.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func (ctx *KimgContext) SaveImage(data []byte) (*KimgResponse, error) {
// GetImage get a image data from kimg according to a image request.
func (ctx *KimgContext) GetImage(req *KimgRequest) ([]byte, error) {

ctx.Logger.Debug("GetImage md5Sum: %s", req.Md5)
ctx.Logger.Debug("GetImage md5Sum: %s, req: %#v", req.Md5, req)

cacheKey := ctx.cacheKey(req)

Expand Down
13 changes: 9 additions & 4 deletions httpd.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,9 @@ func (ctx *KimgContext) isAllowedType(fileType string) bool {
return true
}
}
if "none" == fileType {
return true
}
return false
}

Expand Down Expand Up @@ -347,11 +350,13 @@ func (ctx *KimgContext) genRequest(r *http.Request, md5Sum string) *KimgRequest

if v, ok := r.Form["q"]; ok {
req.Quality, _ = strconv.Atoi(v[0])
}
if req.Quality <= 0 {
if req.Quality < 0 {
req.Quality = ctx.Config.Image.Quality
} else if req.Quality > 100 {
req.Quality = 100
}
} else {
req.Quality = ctx.Config.Image.Quality
} else if req.Quality > 100 {
req.Quality = 100
}

if v, ok := r.Form["r"]; ok {
Expand Down
131 changes: 90 additions & 41 deletions image.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"math"
"net/url"
"strings"

"gopkg.in/gographics/imagick.v3/imagick"
)
Expand Down Expand Up @@ -62,12 +63,31 @@ func (image *KimgImagick) Info(req *KimgRequest, data []byte) (*KimgResponse, er
return nil, err
}

size, _ := mw.GetImageLength()
width := mw.GetImageWidth()
height := mw.GetImageHeight()
width := uint(0)
height := uint(0)
format := mw.GetImageFormat()
size, _ := mw.GetImageLength()
orientationType := mw.GetImageOrientation()

if "GIF" == format {
aw := mw.CoalesceImages()
defer aw.Destroy()
for i := 0; i < int(aw.GetNumberImages()); i++ {
aw.SetIteratorIndex(i)
w := aw.GetImageWidth()
h := aw.GetImageHeight()
if w > width {
width = w
}
if h > height {
height = h
}
}
} else {
width = mw.GetImageWidth()
height = mw.GetImageHeight()
}

exif := make(map[string]string)
names := mw.GetImageProperties("*")
for _, name := range names {
Expand Down Expand Up @@ -99,6 +119,16 @@ func (image *KimgImagick) Convert(data []byte, req KimgRequest) ([]byte, error)
image.ctx.Logger.Warn("ReadImageBlob err: %s", err)
return nil, err
}
mw.ResetIterator()

if "none" != req.Format {
err = mw.SetImageFormat(strings.ToUpper(req.Format))
if err != nil {
image.ctx.Logger.Warn("SetImageFormat %s, err: %s", req.Format, err)
return nil, err
}
image.ctx.Logger.Debug("SetImageFormat %s", req.Format)
}

if req.AutoOrient {
if err := mw.AutoOrientImage(); err != nil {
Expand All @@ -116,15 +146,52 @@ func (image *KimgImagick) Convert(data []byte, req KimgRequest) ([]byte, error)
image.ctx.Logger.Debug("StripImage")
}

if req.Scale {
if err = image.scale(mw, &req); err != nil {
var newData []byte
format := mw.GetImageFormat()
if "GIF" == format {
delay := mw.GetImageDelay()
aw := mw.CoalesceImages()
mw.Destroy()
defer aw.Destroy()

mw = imagick.NewMagickWand()
mw.SetImageDelay(delay)
for i := 0; i < int(aw.GetNumberImages()); i++ {
aw.SetIteratorIndex(i)
img := aw.GetImage()
defer img.Destroy()
if err = image.convertImage(img, &req); err == nil {
mw.AddImage(img)
}
}
mw.OptimizeImageLayers()
mw.ResetIterator()
newData = mw.GetImagesBlob()
} else {
if err = image.convertImage(mw, &req); err != nil {
return nil, err
}
newData = mw.GetImageBlob()
}

if newData == nil || len(newData) == 0 {
image.ctx.Logger.Warn("GetImageBlob failed")
return nil, errors.New("GetImageBlob failed")
}

return newData, nil
}

func (image *KimgImagick) convertImage(mw *imagick.MagickWand, req *KimgRequest) error {
if req.Scale {
if err := image.scale(mw, req); err != nil {
return err
}
}

if req.Crop {
if err = image.crop(mw, &req); err != nil {
return nil, err
if err := image.crop(mw, req); err != nil {
return err
}
}

Expand All @@ -133,61 +200,42 @@ func (image *KimgImagick) Convert(data []byte, req KimgRequest) ([]byte, error)
defer background.Destroy()
if len(req.BGColor) > 0 && !background.SetColor(req.BGColor) {
image.ctx.Logger.Warn("background.SetColor %s failed", req.BGColor)
return nil, errors.New("background.SetColor failed")
return errors.New("background.SetColor failed")
}
err = mw.RotateImage(background, float64(req.Rotate))
if err != nil {
if err := mw.RotateImage(background, float64(req.Rotate)); err != nil {
image.ctx.Logger.Warn("RotateImage %f, err: %s", req.Rotate, err)
return nil, err
return err
}
image.ctx.Logger.Debug("RotateImage %d #%s", req.Rotate, req.BGColor)
}

if len(req.Text) > 0 {
if err = image.waterMark(mw, &req); err != nil {
return nil, err
if err := image.waterMark(mw, req); err != nil {
return err
}
}

if req.Gray {
err = mw.SetImageType(imagick.IMAGE_TYPE_GRAYSCALE)
if err != nil {
if err := mw.SetImageType(imagick.IMAGE_TYPE_GRAYSCALE); err != nil {
image.ctx.Logger.Warn("SetImageType gray, err: %s", err)
return nil, err
return err
}
image.ctx.Logger.Debug("SetImageType gray")
}

err = mw.SetImageCompressionQuality(uint(req.Quality))
if err != nil {
image.ctx.Logger.Warn("SetImageCompressionQuality %d, err: %s", req.Quality, err)
return nil, err
}
image.ctx.Logger.Debug("SetImageCompressionQuality %d", req.Quality)

if "none" != req.Format {
err = mw.SetImageFormat(req.Format)
if err != nil {
image.ctx.Logger.Warn("SetImageFormat %s, err: %s", req.Format, err)
return nil, err
if req.Quality > 0 {
if err := mw.SetImageCompressionQuality(uint(req.Quality)); err != nil {
image.ctx.Logger.Warn("SetImageCompressionQuality %d, err: %s", req.Quality, err)
return err
}
image.ctx.Logger.Debug("SetImageFormat %s", req.Format)
image.ctx.Logger.Debug("SetImageCompressionQuality %d", req.Quality)
}

newData := mw.GetImageBlob()
if newData == nil || len(newData) == 0 {
image.ctx.Logger.Warn("GetImageBlob failed")
return nil, errors.New("GetImageBlob failed")
}

return newData, nil
return nil
}

func (image *KimgImagick) scale(mw *imagick.MagickWand, req *KimgRequest) error {
var w, h uint

w = mw.GetImageWidth()
h = mw.GetImageHeight()
w := mw.GetImageWidth()
h := mw.GetImageHeight()

if req.ScaleP > 0 {
req.ScaleW = round(float64(w) * float64(req.ScaleP) / 100.0)
Expand Down Expand Up @@ -231,6 +279,7 @@ func (image *KimgImagick) scale(mw *imagick.MagickWand, req *KimgRequest) error
if req.ScaleH <= 0 {
req.ScaleH = 1
}

if err := mw.ResizeImage(uint(req.ScaleW), uint(req.ScaleH), imagick.FILTER_LANCZOS); err != nil {
image.ctx.Logger.Warn("ResizeImage %d %d, err: %s", req.ScaleW, req.ScaleH, err)
return err
Expand Down
3 changes: 2 additions & 1 deletion web/src/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class IntegerStep extends React.Component {
</Col>
<Col span={4}>
<InputNumber
min={1}
min={0}
max={100}
formatter={value => `${value}%`}
parser={value => value.replace('%', '')}
Expand Down Expand Up @@ -129,6 +129,7 @@ const ImageBasicQueryForm = Form.create({
<FormItem label="Format">
{getFieldDecorator('f', { initialValue: defaultQuery.f })(
<RadioGroup buttonStyle="solid">
<RadioButton value='none'>NONE</RadioButton>
<RadioButton value='jpg'>JPG</RadioButton>
<RadioButton value='png'>PNG</RadioButton>
<RadioButton value='webp'>WEBP</RadioButton>
Expand Down

0 comments on commit c931e3c

Please sign in to comment.