Go - freetype(因zc原因被鎖, 重新發送)
文字向量繪製圖形, AND 貼上到圖片上。
如果中文亂碼請換字型(字型的TrueType需要是cmap編碼)
!! 還有 , 要‘kxsw’。
如果不能‘kxsw’, 這裡有曲線救國的方式
cd src mkdir golang.org && cd golang.org mkdirx 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--