文字矢量绘制图形, 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--
有疑问加站长微信联系(非本文作者)