text.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. package image
  2. import (
  3. "fmt"
  4. "gopkg.in/gographics/imagick.v3/imagick"
  5. "icloudapp.cn/tools/util"
  6. "strings"
  7. )
  8. type Text struct {
  9. //字体内容
  10. Text string
  11. //字体
  12. Font string
  13. //字体大小
  14. FontSize float64
  15. //字体格式
  16. FontFamily string
  17. //文字颜色
  18. Color string
  19. //文字区域背景颜色
  20. Background string
  21. //文字背景色
  22. UnderColor string
  23. //下划线
  24. UnderLine bool
  25. //删除线
  26. Strike bool
  27. //斜体
  28. Italic bool
  29. //粗体
  30. Bold bool
  31. //字体间隙
  32. WordSpace int
  33. //是否自动换行
  34. Wrap bool
  35. //对齐方式 left center right
  36. Align string
  37. //坐标
  38. ViewPoint *Point
  39. //文字区域大小
  40. ViewSize *Size
  41. Angle int64
  42. }
  43. // NewText text对象
  44. func NewText(font string, fontSize float64, fontFamily string) *Text {
  45. TextInstance := &Text{
  46. Font: font,
  47. FontSize: fontSize,
  48. FontFamily: fontFamily,
  49. }
  50. TextInstance.Clean()
  51. return TextInstance
  52. }
  53. func (t *Text) SetText(text string) {
  54. t.Text = text
  55. }
  56. func (t *Text) SetFont(font string) {
  57. t.Font = font
  58. }
  59. func (t *Text) SetFontSize(fontSize float64) {
  60. t.FontSize = fontSize
  61. }
  62. func (t *Text) SetFontFamily(fontFamily string) {
  63. t.FontFamily = fontFamily
  64. }
  65. func (t *Text) SetColor(color string) {
  66. t.Color = color
  67. }
  68. func (t *Text) SetBackground(background string) {
  69. t.Background = background
  70. }
  71. func (t *Text) SetUnderColor(underColor string) {
  72. t.UnderColor = underColor
  73. }
  74. func (t *Text) SetUnderLine(underLine bool) {
  75. t.UnderLine = underLine
  76. }
  77. func (t *Text) SetStrike(strike bool) {
  78. t.Strike = strike
  79. }
  80. func (t *Text) SetBius(bius string) {
  81. t.SetItalic(false)
  82. t.SetBold(false)
  83. t.SetUnderLine(false)
  84. t.SetStrike(false)
  85. for _, v := range bius {
  86. if string(v) == "i" {
  87. t.SetItalic(true)
  88. }
  89. if string(v) == "b" {
  90. t.SetBold(true)
  91. }
  92. if string(v) == "u" {
  93. t.SetUnderLine(true)
  94. }
  95. if string(v) == "s" {
  96. t.SetStrike(true)
  97. }
  98. }
  99. }
  100. func (t *Text) SetItalic(italic bool) {
  101. t.Italic = italic
  102. }
  103. func (t *Text) SetBold(bold bool) {
  104. t.Bold = bold
  105. }
  106. func (t *Text) SetWordSpace(wordSpace int) {
  107. t.WordSpace = wordSpace
  108. }
  109. func (t *Text) SetWrap(wrap bool) {
  110. t.Wrap = wrap
  111. }
  112. func (t *Text) SetAlign(align string) {
  113. t.Align = align
  114. }
  115. func (t *Text) SetViewPoint(x, y float64) {
  116. t.ViewPoint = NewPoint(x, y)
  117. }
  118. func (t *Text) SetSize(w, h uint) {
  119. t.ViewSize = NewSize(w, h)
  120. }
  121. func (t *Text) SetAngle(angle int64) {
  122. t.Angle = angle
  123. }
  124. func (t *Text) Create() (*imagick.MagickWand, error) {
  125. txtDraw := imagick.NewDrawingWand()
  126. if t.Font != "" {
  127. if err := txtDraw.SetFont(fmt.Sprintf("upload/fonts/%s", t.Font)); err != nil {
  128. return nil, util.NewError("txtDraw.SetFont", err.Error())
  129. }
  130. }
  131. if t.FontSize == 0 {
  132. t.FontSize = 20
  133. }
  134. txtDraw.SetFontSize(t.FontSize)
  135. if t.FontFamily != "" {
  136. if err := txtDraw.SetFontFamily(t.FontFamily); err != nil {
  137. return nil, util.NewError("txtDraw.SetFont", err.Error())
  138. }
  139. }
  140. if t.Color != "" {
  141. tColor := Pixel(t.Color)
  142. txtDraw.SetFillColor(tColor)
  143. }
  144. if t.Italic || t.Bold || t.UnderLine || t.Strike {
  145. txtDraw.SetStrokeColor(Pixel(t.Color))
  146. }
  147. if t.Italic {
  148. txtDraw.SkewX(-12)
  149. }
  150. txtDraw.SetFontStyle(imagick.STYLE_NORMAL)
  151. if t.Bold {
  152. txtDraw.SetStrokeWidth(1)
  153. txtDraw.SetFontStyle(imagick.STYLE_OBLIQUE)
  154. }
  155. if t.UnderLine {
  156. txtDraw.SetTextDecoration(imagick.DECORATION_UNDERLINE)
  157. }
  158. if t.Background != "" {
  159. tb := Pixel(t.Background)
  160. txtDraw.SetTextUnderColor(tb)
  161. }
  162. txtDraw.SetTextEncoding("UTF-8")
  163. if t.Wrap {
  164. txtArr := t.WapText(txtDraw, t.Text, t.Wrap)
  165. t.Text = strings.Join(txtArr, "\n")
  166. }
  167. //透明图片
  168. subMw := imagick.NewMagickWand()
  169. var mwBackground *imagick.PixelWand
  170. if t.Background == "" {
  171. mwBackground = OpacityPixel()
  172. } else {
  173. mwBackground = Pixel(t.Background)
  174. }
  175. if err := subMw.NewImage(t.ViewSize.Width, t.ViewSize.Height, mwBackground); err != nil {
  176. return nil, util.NewError("subMw.NewImage", err.Error())
  177. }
  178. if err := subMw.SetImageFormat("PNG"); err != nil {
  179. return nil, util.NewError("subMw.SetImageFormat", err.Error())
  180. }
  181. metrics := subMw.QueryFontMetrics(txtDraw, t.Text)
  182. alignX := 0.0
  183. if t.Align == "center" {
  184. txtDraw.SetTextAlignment(imagick.ALIGN_CENTER)
  185. alignX = float64(t.ViewSize.Width) / 2
  186. }
  187. if t.Align == "right" {
  188. txtDraw.SetTextAlignment(imagick.ALIGN_RIGHT)
  189. alignX = float64(t.ViewSize.Width)
  190. }
  191. if t.Strike {
  192. txtDraw.SetStrokeDashOffset(metrics.TextHeight)
  193. txtDraw.SetTextDecoration(imagick.DECORATION_LINE_THROUGH)
  194. }
  195. txtDraw.Annotation(alignX, metrics.Ascender, t.Text)
  196. if err := subMw.DrawImage(txtDraw); err != nil {
  197. return nil, util.NewError("subMw.DrawImage", err.Error())
  198. }
  199. parentMw := imagick.NewMagickWand()
  200. if err := parentMw.NewImage(t.ViewSize.Width, t.ViewSize.Height, mwBackground); err != nil {
  201. return nil, util.NewError("subMw.NewImage", err.Error())
  202. }
  203. if err := parentMw.CompositeImage(subMw, imagick.COMPOSITE_OP_OVER, true, 0, 0); err != nil {
  204. return nil, util.NewError("parentMw.CompositeImage ", err.Error())
  205. }
  206. if err := parentMw.RotateImage(OpacityPixel(), float64(t.Angle)); err != nil {
  207. return nil, util.NewError("subMw.RotateImage", err.Error())
  208. }
  209. //由于图片旋转,图片的长宽和坐标位置发生变化,所以需要重置坐标位置
  210. if t.Angle > 0 {
  211. width := parentMw.GetImageWidth()
  212. height := parentMw.GetImageHeight()
  213. y := t.ViewPoint.Y - float64(height)/2 + float64(t.ViewSize.Height)/2
  214. x := t.ViewPoint.X - float64(width)/2 + float64(t.ViewSize.Width)/2
  215. t.ViewPoint.X = x
  216. t.ViewPoint.Y = y
  217. t.ViewSize.Width = width
  218. t.ViewSize.Height = height
  219. }
  220. return parentMw, nil
  221. }
  222. func (t *Text) WapText(dw *imagick.DrawingWand, text string, autoWrap bool) []string {
  223. queryMw := imagick.NewMagickWand()
  224. if err := queryMw.NewImage(t.ViewSize.Width, t.ViewSize.Height, OpacityPixel()); err != nil {
  225. return []string{}
  226. }
  227. metrics := queryMw.QueryFontMetrics(dw, t.Text)
  228. var lines []string
  229. if uint(metrics.TextWidth) <= t.ViewSize.Width {
  230. lines = append(lines, text)
  231. return lines
  232. }
  233. txtRune := []rune(text)
  234. var tmpRune []string
  235. for _, v := range txtRune {
  236. tmpRune = append(tmpRune, string(v))
  237. metrics = queryMw.QueryFontMetrics(dw, strings.Join(tmpRune, ""))
  238. if uint(metrics.TextWidth) >= t.ViewSize.Width {
  239. lines = append(lines, strings.Join(tmpRune[0:len(tmpRune)-1], ""))
  240. tmpRune = []string{}
  241. tmpRune = append(tmpRune, string(v))
  242. }
  243. }
  244. if len(tmpRune) > 0 {
  245. lines = append(lines, strings.Join(tmpRune, ""))
  246. }
  247. return lines
  248. }
  249. func (t *Text) Clean() {
  250. t.SetColor("#ffffff00")
  251. t.SetBackground("#ffffffff")
  252. t.SetSize(0, 0)
  253. t.SetViewPoint(0, 0)
  254. t.SetAlign("left")
  255. t.SetBius("")
  256. t.SetAngle(0)
  257. }