123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- package utils
- import (
- "bytes"
- "fmt"
- "image"
- "image/color"
- "image/draw"
- "image/gif"
- "image/jpeg"
- "image/png"
- "io/ioutil"
- "net/http"
- "os"
- "github.com/golang/freetype"
- "github.com/golang/freetype/truetype"
- "golang.org/x/image/font"
- )
- //DrawTextInfo 图片绘字信息
- type DrawTextInfo struct {
- Text string
- X int
- Y int
- FontSize int
- }
- //DrawRectInfo 图片画框信息
- type DrawRectInfo struct {
- X1 int
- Y1 int
- X2 int
- Y2 int
- }
- //TextBrush 字体相关
- type TextBrush struct {
- FontType *truetype.Font
- FontSize float64
- FontColor *image.Uniform
- TextWidth int
- }
- //NewTextBrush 新生成笔刷
- func NewTextBrush(FontFilePath string, FontSize float64, FontColor *image.Uniform, textWidth int) (*TextBrush, error) {
- fontFile, err := ioutil.ReadFile(FontFilePath)
- if err != nil {
- return nil, err
- }
- fontType, err := truetype.Parse(fontFile)
- if err != nil {
- return nil, err
- }
- if textWidth <= 0 {
- textWidth = 20
- }
- return &TextBrush{FontType: fontType, FontSize: FontSize, FontColor: FontColor, TextWidth: textWidth}, nil
- }
- //DrawFontOnRGBA 图片插入文字
- func (fb *TextBrush) DrawFontOnRGBA(rgba *image.RGBA, pt image.Point, content string) {
- c := freetype.NewContext()
- c.SetDPI(72)
- c.SetFont(fb.FontType)
- c.SetHinting(font.HintingFull)
- c.SetFontSize(fb.FontSize)
- c.SetClip(rgba.Bounds())
- c.SetDst(rgba)
- c.SetSrc(fb.FontColor)
- c.DrawString(content, freetype.Pt(pt.X, pt.Y))
- }
- //Image2RGBA Image2RGBA
- func Image2RGBA(img image.Image) *image.RGBA {
- baseSrcBounds := img.Bounds().Max
- newWidth := baseSrcBounds.X
- newHeight := baseSrcBounds.Y
- des := image.NewRGBA(image.Rect(0, 0, newWidth, newHeight)) // 底板
- //首先将一个图片信息存入jpg
- draw.Draw(des, des.Bounds(), img, img.Bounds().Min, draw.Over)
- return des
- }
- type FontRGBA struct {
- R uint8
- G uint8
- B uint8
- A uint8
- }
- //DrawStringOnImageAndSave 图片上写文字
- func DrawStringOnImageAndSave(imagePath string, imageData []byte, infos []*DrawTextInfo, colorRGBA FontRGBA) (err error) {
- //判断图片类型
- var backgroud image.Image
- filetype := http.DetectContentType(imageData)
- switch filetype {
- case "image/jpeg", "image/jpg":
- backgroud, err = jpeg.Decode(bytes.NewReader(imageData))
- if err != nil {
- fmt.Println("jpeg error")
- return err
- }
- case "image/gif":
- backgroud, err = gif.Decode(bytes.NewReader(imageData))
- if err != nil {
- return err
- }
- case "image/png":
- backgroud, err = png.Decode(bytes.NewReader(imageData))
- if err != nil {
- return err
- }
- default:
- return err
- }
- des := Image2RGBA(backgroud)
- //新建笔刷
- ttfPath := "static/ttf/songti.ttf"
- textBrush, _ := NewTextBrush(ttfPath, 25, image.Black, 50)
- //Px Py 绘图开始坐标 text要绘制的文字
- //调整颜色
- c := freetype.NewContext()
- c.SetDPI(72)
- c.SetFont(textBrush.FontType)
- c.SetHinting(font.HintingFull)
- c.SetFontSize(textBrush.FontSize)
- c.SetClip(des.Bounds())
- c.SetDst(des)
- textBrush.FontColor = image.NewUniform(color.RGBA{
- R: colorRGBA.R,
- G: colorRGBA.G,
- B: colorRGBA.B,
- A: colorRGBA.A,
- })
- c.SetSrc(textBrush.FontColor)
- for _, info := range infos {
- c.DrawString(info.Text, freetype.Pt(info.X, info.Y))
- }
- //保存图片
- fSave, err := os.Create(imagePath)
- if err != nil {
- return err
- }
- defer fSave.Close()
- err = jpeg.Encode(fSave, des, nil)
- if err != nil {
- return err
- }
- return nil
- }
- //DrawRectOnImageAndSave 图片上画多个框
- func DrawRectOnImageAndSave(imagePath string, imageData []byte, infos []*DrawRectInfo) (err error) {
- //判断图片类型
- var backgroud image.Image
- filetype := http.DetectContentType(imageData)
- switch filetype {
- case "image/jpeg", "image/jpg":
- backgroud, err = jpeg.Decode(bytes.NewReader(imageData))
- if err != nil {
- fmt.Println("jpeg error")
- return err
- }
- case "image/gif":
- backgroud, err = gif.Decode(bytes.NewReader(imageData))
- if err != nil {
- return err
- }
- case "image/png":
- backgroud, err = png.Decode(bytes.NewReader(imageData))
- if err != nil {
- return err
- }
- default:
- return err
- }
- des := Image2RGBA(backgroud)
- //新建笔刷
- textBrush, _ := NewTextBrush("arial.ttf", 15, image.Black, 15)
- for _, info := range infos {
- var c *freetype.Context
- c = freetype.NewContext()
- c.SetDPI(72)
- c.SetFont(textBrush.FontType)
- c.SetHinting(font.HintingFull)
- c.SetFontSize(textBrush.FontSize)
- c.SetClip(des.Bounds())
- c.SetDst(des)
- cGreen := image.NewUniform(color.RGBA{
- R: 0,
- G: 0xFF,
- B: 0,
- A: 255,
- })
- c.SetSrc(cGreen)
- for i := info.X1; i < info.X2; i++ {
- c.DrawString("·", freetype.Pt(i, info.Y1))
- c.DrawString("·", freetype.Pt(i, info.Y2))
- }
- for j := info.Y1; j < info.Y2; j++ {
- c.DrawString("·", freetype.Pt(info.X1, j))
- c.DrawString("·", freetype.Pt(info.X2, j))
- }
- }
- //保存图片
- fSave, err := os.Create(imagePath)
- if err != nil {
- return err
- }
- defer fSave.Close()
- err = jpeg.Encode(fSave, des, nil)
- if err != nil {
- return err
- }
- return nil
- }
- //DrawStringOnImage 生成图片
- func DrawStringOnImage(imageData []byte, infos []*DrawTextInfo, colorRGBA FontRGBA, fontSize float64, fontWidth int) (picBytes bytes.Buffer, err error) {
- //判断图片类型
- var backgroud image.Image
- filetype := http.DetectContentType(imageData)
- switch filetype {
- case "image/jpeg", "image/jpg":
- backgroud, err = jpeg.Decode(bytes.NewReader(imageData))
- if err != nil {
- fmt.Println("jpeg error")
- return
- }
- case "image/gif":
- backgroud, err = gif.Decode(bytes.NewReader(imageData))
- if err != nil {
- return
- }
- case "image/png":
- backgroud, err = png.Decode(bytes.NewReader(imageData))
- if err != nil {
- return
- }
- default:
- return
- }
- des := Image2RGBA(backgroud)
- //新建笔刷
- ttfPath := "static/ttf/songti.ttf"
- textBrush, _ := NewTextBrush(ttfPath, fontSize, image.Black, fontWidth)
- //Px Py 绘图开始坐标 text要绘制的文字
- //调整颜色
- c := freetype.NewContext()
- c.SetDPI(72)
- c.SetFont(textBrush.FontType)
- c.SetHinting(font.HintingFull)
- c.SetFontSize(textBrush.FontSize)
- c.SetClip(des.Bounds())
- c.SetDst(des)
- textBrush.FontColor = image.NewUniform(color.RGBA{
- R: colorRGBA.R,
- G: colorRGBA.G,
- B: colorRGBA.B,
- A: colorRGBA.A,
- })
- c.SetSrc(textBrush.FontColor)
- for _, info := range infos {
- c.DrawString(info.Text, freetype.Pt(info.X, info.Y))
- }
- err = jpeg.Encode(&picBytes, des, nil)
- return
- }
- // DrawStringRowsOnImage 生成图片
- func DrawStringRowsOnImage(imageData []byte, infos []*DrawTextInfo, colorRGBA FontRGBA, fontSize float64, fontWidth int) (picBytes bytes.Buffer, err error) {
- //判断图片类型
- var backgroud image.Image
- filetype := http.DetectContentType(imageData)
- switch filetype {
- case "image/jpeg", "image/jpg":
- backgroud, err = jpeg.Decode(bytes.NewReader(imageData))
- if err != nil {
- fmt.Println("jpeg error")
- return
- }
- case "image/gif":
- backgroud, err = gif.Decode(bytes.NewReader(imageData))
- if err != nil {
- return
- }
- case "image/png":
- backgroud, err = png.Decode(bytes.NewReader(imageData))
- if err != nil {
- return
- }
- default:
- return
- }
- des := Image2RGBA(backgroud)
- //新建笔刷
- ttfPath := "static/ttf/songti.ttf"
- textBrush, _ := NewTextBrush(ttfPath, fontSize, image.Black, fontWidth)
- //Px Py 绘图开始坐标 text要绘制的文字
- //调整颜色
- for _, info := range infos {
- c := freetype.NewContext()
- c.SetDPI(72)
- c.SetFont(textBrush.FontType)
- c.SetHinting(font.HintingFull)
- c.SetFontSize(float64(info.FontSize))
- c.SetClip(des.Bounds())
- c.SetDst(des)
- textBrush.FontColor = image.NewUniform(color.RGBA{
- R: colorRGBA.R,
- G: colorRGBA.G,
- B: colorRGBA.B,
- A: colorRGBA.A,
- })
- c.SetSrc(textBrush.FontColor)
- c.DrawString(info.Text, freetype.Pt(info.X, info.Y))
- }
- err = jpeg.Encode(&picBytes, des, nil)
- return
- }
|