poster.go 4.2 KB

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