package image import ( "fmt" "gopkg.in/gographics/imagick.v3/imagick" "icloudapp.cn/tools/util" "strings" ) type Text struct { //字体内容 Text string //字体 Font string //字体大小 FontSize float64 //字体格式 FontFamily string //文字颜色 Color string //文字区域背景颜色 Background string //文字背景色 UnderColor string //下划线 UnderLine bool //删除线 Strike bool //斜体 Italic bool //粗体 Bold bool //字体间隙 WordSpace int //是否自动换行 Wrap bool //对齐方式 left center right Align string //坐标 ViewPoint *Point //文字区域大小 ViewSize *Size Angle int64 } // NewText text对象 func NewText(font string, fontSize float64, fontFamily string) *Text { TextInstance := &Text{ Font: font, FontSize: fontSize, FontFamily: fontFamily, } TextInstance.Clean() return TextInstance } func (t *Text) SetText(text string) { t.Text = text } func (t *Text) SetFont(font string) { t.Font = font } func (t *Text) SetFontSize(fontSize float64) { t.FontSize = fontSize } func (t *Text) SetFontFamily(fontFamily string) { t.FontFamily = fontFamily } func (t *Text) SetColor(color string) { t.Color = color } func (t *Text) SetBackground(background string) { t.Background = background } func (t *Text) SetUnderColor(underColor string) { t.UnderColor = underColor } func (t *Text) SetUnderLine(underLine bool) { t.UnderLine = underLine } func (t *Text) SetStrike(strike bool) { t.Strike = strike } func (t *Text) SetBius(bius string) { t.SetItalic(false) t.SetBold(false) t.SetUnderLine(false) t.SetStrike(false) for _, v := range bius { if string(v) == "i" { t.SetItalic(true) } if string(v) == "b" { t.SetBold(true) } if string(v) == "u" { t.SetUnderLine(true) } if string(v) == "s" { t.SetStrike(true) } } } func (t *Text) SetItalic(italic bool) { t.Italic = italic } func (t *Text) SetBold(bold bool) { t.Bold = bold } func (t *Text) SetWordSpace(wordSpace int) { t.WordSpace = wordSpace } func (t *Text) SetWrap(wrap bool) { t.Wrap = wrap } func (t *Text) SetAlign(align string) { t.Align = align } func (t *Text) SetViewPoint(x, y float64) { t.ViewPoint = NewPoint(x, y) } func (t *Text) SetSize(w, h uint) { t.ViewSize = NewSize(w, h) } func (t *Text) SetAngle(angle int64) { t.Angle = angle } func (t *Text) Create() (*imagick.MagickWand, error) { txtDraw := imagick.NewDrawingWand() if t.Font != "" { if err := txtDraw.SetFont(fmt.Sprintf("upload/fonts/%s", t.Font)); err != nil { return nil, util.NewError("txtDraw.SetFont", err.Error()) } } if t.FontSize == 0 { t.FontSize = 20 } txtDraw.SetFontSize(t.FontSize) if t.FontFamily != "" { if err := txtDraw.SetFontFamily(t.FontFamily); err != nil { return nil, util.NewError("txtDraw.SetFont", err.Error()) } } if t.Color != "" { tColor := Pixel(t.Color) txtDraw.SetFillColor(tColor) } if t.Italic || t.Bold || t.UnderLine || t.Strike { txtDraw.SetStrokeColor(Pixel(t.Color)) } if t.Italic { txtDraw.SkewX(-12) } txtDraw.SetFontStyle(imagick.STYLE_NORMAL) if t.Bold { txtDraw.SetStrokeWidth(1) txtDraw.SetFontStyle(imagick.STYLE_OBLIQUE) } if t.UnderLine { txtDraw.SetTextDecoration(imagick.DECORATION_UNDERLINE) } if t.Background != "" { tb := Pixel(t.Background) txtDraw.SetTextUnderColor(tb) } txtDraw.SetTextEncoding("UTF-8") if t.Wrap { txtArr := t.WapText(txtDraw, t.Text, t.Wrap) t.Text = strings.Join(txtArr, "\n") } //透明图片 subMw := imagick.NewMagickWand() var mwBackground *imagick.PixelWand if t.Background == "" { mwBackground = OpacityPixel() } else { mwBackground = Pixel(t.Background) } if err := subMw.NewImage(t.ViewSize.Width, t.ViewSize.Height, mwBackground); err != nil { return nil, util.NewError("subMw.NewImage", err.Error()) } if err := subMw.SetImageFormat("PNG"); err != nil { return nil, util.NewError("subMw.SetImageFormat", err.Error()) } metrics := subMw.QueryFontMetrics(txtDraw, t.Text) alignX := 0.0 if t.Align == "center" { txtDraw.SetTextAlignment(imagick.ALIGN_CENTER) alignX = float64(t.ViewSize.Width) / 2 } if t.Align == "right" { txtDraw.SetTextAlignment(imagick.ALIGN_RIGHT) alignX = float64(t.ViewSize.Width) } if t.Strike { txtDraw.SetStrokeDashOffset(metrics.TextHeight) txtDraw.SetTextDecoration(imagick.DECORATION_LINE_THROUGH) } txtDraw.Annotation(alignX, metrics.Ascender, t.Text) if err := subMw.DrawImage(txtDraw); err != nil { return nil, util.NewError("subMw.DrawImage", err.Error()) } parentMw := imagick.NewMagickWand() if err := parentMw.NewImage(t.ViewSize.Width, t.ViewSize.Height, mwBackground); err != nil { return nil, util.NewError("subMw.NewImage", err.Error()) } if err := parentMw.CompositeImage(subMw, imagick.COMPOSITE_OP_OVER, true, 0, 0); err != nil { return nil, util.NewError("parentMw.CompositeImage ", err.Error()) } if err := parentMw.RotateImage(OpacityPixel(), float64(t.Angle)); err != nil { return nil, util.NewError("subMw.RotateImage", err.Error()) } //由于图片旋转,图片的长宽和坐标位置发生变化,所以需要重置坐标位置 if t.Angle > 0 { width := parentMw.GetImageWidth() height := parentMw.GetImageHeight() y := t.ViewPoint.Y - float64(height)/2 + float64(t.ViewSize.Height)/2 x := t.ViewPoint.X - float64(width)/2 + float64(t.ViewSize.Width)/2 t.ViewPoint.X = x t.ViewPoint.Y = y t.ViewSize.Width = width t.ViewSize.Height = height } return parentMw, nil } func (t *Text) WapText(dw *imagick.DrawingWand, text string, autoWrap bool) []string { queryMw := imagick.NewMagickWand() if err := queryMw.NewImage(t.ViewSize.Width, t.ViewSize.Height, OpacityPixel()); err != nil { return []string{} } metrics := queryMw.QueryFontMetrics(dw, t.Text) var lines []string if uint(metrics.TextWidth) <= t.ViewSize.Width { lines = append(lines, text) return lines } txtRune := []rune(text) var tmpRune []string for _, v := range txtRune { tmpRune = append(tmpRune, string(v)) metrics = queryMw.QueryFontMetrics(dw, strings.Join(tmpRune, "")) if uint(metrics.TextWidth) >= t.ViewSize.Width { lines = append(lines, strings.Join(tmpRune[0:len(tmpRune)-1], "")) tmpRune = []string{} tmpRune = append(tmpRune, string(v)) } } if len(tmpRune) > 0 { lines = append(lines, strings.Join(tmpRune, "")) } return lines } func (t *Text) Clean() { t.SetColor("#ffffff00") t.SetBackground("#ffffffff") t.SetSize(0, 0) t.SetViewPoint(0, 0) t.SetAlign("left") t.SetBius("") t.SetAngle(0) }