poster.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package image
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "gopkg.in/gographics/imagick.v3/imagick"
  7. "icloudapp.cn/tools/util"
  8. "strings"
  9. )
  10. type Poster struct {
  11. ctx context.Context
  12. Path string
  13. CachePath string
  14. }
  15. func NewPoster(ctx context.Context) *Poster {
  16. poster := &Poster{ctx: ctx}
  17. poster.Path = util.Getwd()
  18. poster.CachePath = fmt.Sprintf("%s/cache", util.Getwd())
  19. return poster
  20. }
  21. func (p *Poster) Image(item Items) (*imagick.MagickWand, Items, error) {
  22. util.TimeCost("Draw Image " + item.Value)()
  23. var updated Items
  24. image := NewImage(p.Path)
  25. image.SetCache(p.CachePath)
  26. image.SetFile(item.Value)
  27. image.SetSize(item.Width, item.Height)
  28. image.SetAngle(float64(item.Angle))
  29. image.SetPoint(float64(item.X), float64(item.Y))
  30. drawMw, err := image.Create()
  31. updated = item
  32. updated.X = int(image.ViewPoint.X)
  33. updated.Y = int(image.ViewPoint.Y)
  34. return drawMw, updated, err
  35. }
  36. func (p *Poster) Text(item Items) (*imagick.MagickWand, Items, error) {
  37. util.TimeCost("Draw Text " + item.Value)()
  38. var updated Items
  39. item.Value = strings.Replace(item.Value, " ", " ", -1)
  40. txt := NewText(item.Font, float64(item.Size), "")
  41. txt.SetText(item.Value)
  42. txt.SetColor(item.Color)
  43. txt.SetBackground(item.Background)
  44. txt.SetSize(item.Width, item.Height)
  45. txt.SetViewPoint(float64(item.X), float64(item.Y))
  46. txt.SetAlign(*item.Align)
  47. txt.SetBius(*item.Bius)
  48. txt.SetAngle(int64(item.Angle))
  49. if *item.Wrap {
  50. txt.SetWrap(*item.Wrap)
  51. }
  52. mw, err := txt.Create()
  53. updated = item
  54. updated.X = int(txt.ViewPoint.X)
  55. updated.Y = int(txt.ViewPoint.Y)
  56. updated.Width = txt.ViewSize.Width
  57. updated.Height = txt.ViewSize.Height
  58. return mw, updated, err
  59. }
  60. func (p *Poster) QRCode(item Items) (*imagick.MagickWand, Items, error) {
  61. util.TimeCost("QRCode Image " + item.Value)()
  62. var updated Items
  63. qr := NewQR()
  64. qr.SetCache(p.CachePath)
  65. qr.SetValue(item.Value)
  66. qr.SetSize(item.Width, item.Height)
  67. qr.SetBackgroundColor(item.Background)
  68. qr.SetFrontColor(item.Color)
  69. qr.SetViewPoint(float64(item.X), float64(item.Y))
  70. qr.SetAngle(float64(item.Angle))
  71. mw, err := qr.Create()
  72. updated = item
  73. updated.X = int(qr.ViewPoint.X)
  74. updated.Y = int(qr.ViewPoint.Y)
  75. return mw, updated, err
  76. }
  77. func (p *Poster) Avatar(item Items) (*imagick.MagickWand, Items, error) {
  78. util.TimeCost("Draw Avatar " + item.Value)()
  79. var updated Items
  80. avatar := NewAvatar()
  81. avatar.SetBorder(1)
  82. avatar.SetBackgroundColor(item.Background)
  83. avatar.SetAvatar(item.Value)
  84. avatar.SetSize(item.Width, item.Height)
  85. avatar.SetViewPoint(float64(item.X), float64(item.Y))
  86. mw, err := avatar.Create()
  87. updated = item
  88. updated.X = int(avatar.ViewPoint.X)
  89. updated.Y = int(avatar.ViewPoint.Y)
  90. return mw, updated, err
  91. }
  92. type PosterMW struct {
  93. Index int
  94. Image *imagick.MagickWand
  95. Item Items
  96. Err error
  97. }
  98. func (p *Poster) Create(json PosterJson) (*imagick.MagickWand, error) {
  99. defer util.TimeCost("创建海报")()
  100. if json.Width == 0 || json.Height == 0 {
  101. return nil, errors.New("create poster without width or height")
  102. }
  103. image := NewImage(util.Getwd())
  104. image.SetCache(p.Path)
  105. image.SetCache(p.CachePath)
  106. if json.Use == "bgUrl" {
  107. json.Background = ""
  108. }
  109. if json.Use == "bgc" {
  110. json.BackgroundUrl = ""
  111. }
  112. image.SetSize(json.Width, json.Height)
  113. image.SetPoint(0, 0)
  114. image.SetBackground(json.Background)
  115. image.SetFile(json.BackgroundUrl)
  116. poster, err := image.Create()
  117. if err != nil {
  118. return nil, err
  119. }
  120. itemLen := len(json.Items)
  121. destChan := make(chan *PosterMW, itemLen)
  122. defer close(destChan)
  123. for index, item := range json.Items {
  124. go func(item Items, index int) {
  125. var drawErr error
  126. var drawMW *imagick.MagickWand
  127. if item.Type == "text" {
  128. drawMW, item, drawErr = p.Text(item)
  129. }
  130. // 图片旋转还未做
  131. if item.Type == "image" {
  132. drawMW, item, drawErr = p.Image(item)
  133. }
  134. if item.Type == "qrcode" {
  135. drawMW, item, drawErr = p.QRCode(item)
  136. }
  137. if item.Type == "avatar" {
  138. drawMW, item, drawErr = p.Avatar(item)
  139. }
  140. destChan <- &PosterMW{Index: index, Image: drawMW, Item: item, Err: drawErr}
  141. }(item, index)
  142. }
  143. var response = make([]*PosterMW, itemLen)
  144. for i := 0; i < len(json.Items); i++ {
  145. res := <-destChan
  146. response[res.Index] = res
  147. }
  148. for i := 0; i < len(response); i++ {
  149. draw := response[i].Image
  150. errDraw := response[i].Err
  151. if errDraw != nil {
  152. fmt.Println("poster.errDraw : ", errDraw.Error())
  153. continue
  154. }
  155. if errComposite := poster.CompositeImage(draw, imagick.COMPOSITE_OP_OVER, true, response[i].Item.X, response[i].Item.Y); errComposite != nil {
  156. fmt.Println("poster.CompositeImage err : ", errComposite.Error())
  157. continue
  158. }
  159. }
  160. return poster, nil
  161. }