Go - freetype(因zc原因被锁, 重新发送)

谢秀岳 · · 1028 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

文字矢量绘制图形, AND 粘贴到图片上。

如果中文乱码请换字体(字体的TrueType需要是cmap编码)

!! 还有 , 要‘kxsw’。

如果不能‘kxsw’, 这里有曲线救国的方式

cd src
mkdir golang.org && cd golang.org
mkdir  x 
git clone https://github.com/golang/image

然后去github. clone github.com/golang/freetype

这个包应该是: code.google.com/p/freetype-go/freetype, 但是'天c'有Q a

完整代码如下。

package main

import (
    "github.com/golang/freetype"
    "image"
    //"image/color"
    // "image/png"
    "image/jpeg"
    "io/ioutil"
    "log"
    "os"

    
    "image/draw"
)

const (
    dx = 590 // 图片的大小 宽度
    dy = 500 // 图片的大小 高度
    fontFile = "C:/www/go/src/study/simsun.ttf"
    fontSize = 20 // 字体尺寸
    fontDPI  = 72 // 屏幕每英寸的分辨率
)

func main() {
    // 需要保存的文件
    // imgfile, _ := os.Create("C:/www/go/src/study/out.png")
    // defer imgfile.Close()
    // 新建一个 指定大小的 RGBA位图
    img := image.NewNRGBA(image.Rect(0, 0, dx, dy))
    // 画背景
    /*for y := 0; y < dy; y++ {
        for x := 0; x < dx; x++ {
            // 设置某个点的颜色,依次是 RGBA
            img.Set(x, y, color.RGBA{uint8(x), uint8(y), 0, 255})
        }
    }*/
    // 读字体数据
    fontBytes, err := ioutil.ReadFile(fontFile)
    if err != nil {
        log.Println("读取字体数据出错")
        log.Println(err)
        return
    }
    font, err := freetype.ParseFont(fontBytes)
    if err != nil {
        log.Println("转换字体样式出错")
        log.Println(err)
        return
    }

    c := freetype.NewContext()
    c.SetDPI(fontDPI)
    c.SetFont(font)
    c.SetFontSize(fontSize)
    c.SetClip(img.Bounds())
    c.SetDst(img)
    c.SetSrc(image.Black)

    pt := freetype.Pt(158, 60 * int(c.PointToFixed(fontSize)>>8)) // 字出现的位置

    _, err = c.DrawString("DEBUG", pt)
    if err != nil {
        log.Println("向图片写字体出错")
        log.Println(err)
        return
    }
    //重新第二行的位置
    pt.X += c.PointToFixed(fontSize) * 15
    _, err = c.DrawString("2018-03-06", pt)
    if err != nil {
        log.Println("向图片写字体出错")
        log.Println(err)
        return
    }

    // 以PNG格式保存文件
    // err = png.Encode(imgfile, img)
    // if err != nil {
    //  log.Println("生成图片出错")
    //  log.Fatal(err)
    // }
    hc(img)
}

func hc(imgt *image.NRGBA){
        imgb, _ := os.Open("C:/www/go/src/study/certificate.jpg")
        img, _ := jpeg.Decode(imgb)
        defer imgb.Close()
    
        offset := image.Pt(200, 200)
        b := img.Bounds()
        m := image.NewRGBA(b)
        draw.Draw(m, b, img, image.ZP, draw.Src)
        draw.Draw(m, imgt.Bounds().Add(offset), imgt, image.ZP, draw.Over)
    
        imgw, _ := os.Create("C:/www/go/src/study/out.jpg")
        jpeg.Encode(imgw, m, &jpeg.Options{jpeg.DefaultQuality})
        defer imgw.Close()
}

效果

晚安。( ̄o ̄) . z Z

// 早上更新

因为业务需求, 图片是直接输出的

看了又看。很多文章没讲到如何输出图片, 我现在都没搜索到相关文章。

看代码即可, 关键代码如下

     w.Header().Set("content-type", "image/png")
    var b bytes.Buffer
    png.Encode(&b, doneImg)
    w.Write(b.Bytes())

搜索关键字:go content-type输出image图片

又完整代码如下

package imgaddtext

import (
    "net/http"
    "fmt"
    "encoding/json"
    
    "github.com/golang/freetype"
    "image"
    //"image/color"
    "image/png"
    "image/jpeg"
    "io/ioutil"
    "log"
    "os"
    
    "image/draw"
    "bytes"
)

const (
    baseFile = "D:/www/go/src/yhz/router/imgaddtext/"
)

const (
    dx = 1125 // 图片的大小 宽度
    dy = 1400 // 图片的大小 高度
    fontFile = baseFile + "simsun.ttf"
    fontSize = 42 // 字体尺寸
    fontDPI  = 72 // 屏幕每英寸的分辨率
)



var errorRequest =  struct{
    Code int16
    Msg string
}{}

func Error(msg string) (string){
    errorRequest.Code = 1
    errorRequest.Msg = msg
    re, _ := json.Marshal(errorRequest)
    return string(re)
}

func LackParams(r *http.Request, m []string) (bool, string){
    r.ParseForm()

    for _, val := range m {
        if len(r.Form[val]) == 0 {
            return true, Error("缺少参数")
        }
    }

    return false, ""
}


func Start(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()   
    // 参数缺少验证
    if re, str := LackParams(r, []string{"realName", "wx", "ww", "time"}); re {
        fmt.Fprintf(w, str)
        return
    }
    
    realName := r.Form["realName"][0]
    wxName := r.Form["wx"][0]
    wwName := r.Form["ww"][0]
    timeName := r.Form["time"][0]
    
     // 新建一个 指定大小的 RGBA位图
     img := image.NewNRGBA(image.Rect(0, 0, dx, dy))
     // 画背景
     /*for y := 0; y < dy; y++ {
         for x := 0; x < dx; x++ {
             // 设置某个点的颜色,依次是 RGBA
             img.Set(x, y, color.RGBA{uint8(x), uint8(y), 0, 255})
         }
     }*/
     // 读字体数据
     fontBytes, err := ioutil.ReadFile(fontFile)
     if err != nil {
         log.Println("读取字体数据出错")
         log.Println(err)
         return
     }
     font, err := freetype.ParseFont(fontBytes)
     if err != nil {
         log.Println("转换字体样式出错")
         log.Println(err)
         return
     }
 
     c := freetype.NewContext()
     c.SetDPI(fontDPI)
     c.SetFont(font)
     c.SetFontSize(fontSize)
     c.SetHinting(50)
     c.SetClip(img.Bounds())
     c.SetDst(img)
     c.SetSrc(image.Black)
 
     pt := freetype.Pt(dx / 2 - ((fontSize + 17) * (len([]rune(realName))/2)), dy / 2 + 300) 
 
     _, err = c.DrawString(realName, pt)
     if err != nil {
         log.Println("向图片写字体出错")
         log.Println(err)
         return
     }
     //重新第二行的位置
    //  pt.X += c.PointToFixed(fontSize) * 15
    pt = freetype.Pt(358, dy / 2 + 300 + 90)
    c.SetFontSize(30)
     _, err = c.DrawString(wxName, pt)
     if err != nil {
         log.Println("向图片写字体出错")
         log.Println(err)
         return
     }
     
    pt = freetype.Pt(358, dy / 2 + 200 + 280)
    _, err = c.DrawString(wwName, pt)
    if err != nil {
        log.Println("向图片写字体出错")
        log.Println(err)
        return
    }

    pt = freetype.Pt(150, dy - 10)
    c.SetFontSize(23)
     _, err = c.DrawString(timeName, pt)
     if err != nil {
         log.Println("向图片写字体出错")
         log.Println(err)
         return
     }
     

    doneImg := hc(img)
     
     
     w.Header().Set("content-type", "image/png")
    //  w.Header().Set("Content-Length", fmt.Sprintf("%d", len(img)))
    // re := []byte(img)
    var b bytes.Buffer
    png.Encode(&b, doneImg)
    w.Write(b.Bytes())
}

func hc(imgt *image.NRGBA) *image.RGBA {
    imgb, _ := os.Open(baseFile + "bookbg.png")
    img, _ := png.Decode(imgb)
    defer imgb.Close()

    offset := image.Pt(0, 0)
    b := img.Bounds()
    m := image.NewRGBA(b)
    draw.Draw(m, b, img, image.ZP, draw.Src)
    draw.Draw(m, imgt.Bounds().Add(offset), imgt, image.ZP, draw.Over)

    imgw, _ := os.Create(baseFile + "out.jpg")
    jpeg.Encode(imgw, m, &jpeg.Options{jpeg.DefaultQuality})
    defer imgw.Close()

    return m
}


效果:

--END--


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:谢秀岳

查看原文:Go - freetype(因zc原因被锁, 重新发送)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1028 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传