package image import ( "context" "fmt" "gopkg.in/gographics/imagick.v3/imagick" "icloudapp.cn/tools/util" "strings" ) type Poster struct { ctx context.Context Path string CachePath string } func NewPoster(ctx context.Context) *Poster { poster := &Poster{ctx: ctx} poster.Path = util.Getwd() poster.CachePath = fmt.Sprintf("%s/cache", util.Getwd()) return poster } func (p *Poster) Image(item Items) (*imagick.MagickWand, Items, error) { var updated Items image := NewImage(p.Path) image.SetCache(p.CachePath) image.SetFile(item.Value) image.SetSize(item.Width, item.Height) image.SetAngle(float64(item.Angle)) image.SetPoint(float64(item.X), float64(item.Y)) drawMw, err := image.Create() updated = item updated.X = int(image.ViewPoint.X) updated.Y = int(image.ViewPoint.Y) return drawMw, updated, err } func (p *Poster) Text(item Items) (*imagick.MagickWand, Items, error) { var updated Items item.Value = strings.Replace(item.Value, " ", " ", -1) txt := NewText(item.Font, float64(item.Size), "") txt.SetText(item.Value) txt.SetColor(item.Color) txt.SetBackground(item.Background) txt.SetSize(item.Width, item.Height) txt.SetViewPoint(float64(item.X), float64(item.Y)) txt.SetAlign(*item.Align) txt.SetBius(*item.Bius) txt.SetAngle(int64(item.Angle)) if *item.Wrap { txt.SetWrap(*item.Wrap) } mw, err := txt.Create() updated = item updated.X = int(txt.ViewPoint.X) updated.Y = int(txt.ViewPoint.Y) updated.Width = txt.ViewSize.Width updated.Height = txt.ViewSize.Height return mw, updated, err } func (p *Poster) QRCode(item Items) (*imagick.MagickWand, Items, error) { var updated Items qr := NewQR() qr.SetCache(p.CachePath) qr.SetValue(item.Value) qr.SetSize(item.Width, item.Height) qr.SetBackgroundColor(item.Background) qr.SetFrontColor(item.Color) qr.SetViewPoint(float64(item.X), float64(item.Y)) qr.SetAngle(float64(item.Angle)) mw, err := qr.Create() updated = item updated.X = int(qr.ViewPoint.X) updated.Y = int(qr.ViewPoint.Y) return mw, updated, err } func (p *Poster) Avatar(item Items) (*imagick.MagickWand, Items, error) { var updated Items avatar := NewAvatar() avatar.SetBorder(1) avatar.SetBackgroundColor(item.Background) avatar.SetAvatar(item.Value) avatar.SetSize(item.Width, item.Height) avatar.SetViewPoint(float64(item.X), float64(item.Y)) mw, err := avatar.Create() updated = item updated.X = int(avatar.ViewPoint.X) updated.Y = int(avatar.ViewPoint.Y) return mw, updated, err } type PosterMW struct { Index int Image *imagick.MagickWand Item Items Err error } func (p *Poster) Create(json PosterJson) (*imagick.MagickWand, error) { image := NewImage(util.Getwd()) image.SetCache(p.Path) image.SetCache(p.CachePath) if json.Use == "bgUrl" { json.Background = "" } if json.Use == "bgc" { json.BackgroundUrl = "" } image.SetSize(json.Width, json.Height) image.SetPoint(0, 0) image.SetBackground(json.Background) image.SetFile(json.BackgroundUrl) poster, err := image.Create() if err != nil { return nil, err } itemLen := len(json.Items) destChan := make(chan *PosterMW, itemLen) defer close(destChan) for index, item := range json.Items { go func(item Items, index int) { var drawErr error var drawMW *imagick.MagickWand if item.Type == "text" { drawMW, item, drawErr = p.Text(item) } // 图片旋转还未做 if item.Type == "image" { drawMW, item, drawErr = p.Image(item) } if item.Type == "qrcode" { drawMW, item, drawErr = p.QRCode(item) } if item.Type == "avatar" { drawMW, item, drawErr = p.Avatar(item) } destChan <- &PosterMW{Index: index, Image: drawMW, Item: item, Err: drawErr} }(item, index) } var response = make([]*PosterMW, itemLen) for i := 0; i < len(json.Items); i++ { res := <-destChan response[res.Index] = res } for i := 0; i < len(response); i++ { draw := response[i].Image errDraw := response[i].Err if errDraw != nil { fmt.Println("Response err", errDraw.Error()) continue } if errComposite := poster.CompositeImage(draw, imagick.COMPOSITE_OP_OVER, true, response[i].Item.X, response[i].Item.Y); errComposite != nil { fmt.Println("poster.CompositeImage text err : ", errComposite.Error()) continue } } return poster, nil }