2016-07-11 28 views
17

鑑於image.RGBA,座標和一行文字,我如何使用任何普通固定字體添加簡單標籤?例如。 Face7x13font/basicfont如何在Go中爲圖片添加簡單的文本標籤?

package main 

import (
    "image" 
    "image/color" 
    "image/png" 
    "os" 
) 

func main() { 
    img := image.NewRGBA(image.Rect(0, 0, 320, 240)) 
    x, y := 100, 100 
    addLabel(img, x, y, "Test123") 
    png.Encode(os.Stdout, img) 
} 

func addLabel(img *image.RGBA, x, y int, label string) { 
    col := color.Black 
    // now what? 
} 

對齊並不重要,但最好是如果我可以將標籤寫在以座標開頭的行上方。

我想避免像字體這樣的外部可加載依賴項。

+0

該軟件包明確指出,它只提供字體表面的接口。 ''''其他包提供了字體實現,例如,一個truetype包將提供一個基於.ttf字體文件的文件。「' –

回答

20

golang.org/x/image/font包只是爲圖像上的字體面和繪圖文本定義接口。

您可以使用Freetype字體光柵化器的執行:github.com/golang/freetype

關鍵類型是freetype.Context,它有你需要的所有方法。

有關完整的示例,請查看此文件:example/freetype/main.go。此示例加載字體文件,創建並配置freetype.Context,在圖像上繪製文本並將結果圖像保存到文件。

讓我們假設你已經加載了字體文件,並配置了一個c上下文(請參閱示例如何做)。然後你addLabel()功能看起來是這樣的:

func addLabel(img *image.RGBA, x, y int, label string) { 
    c.SetDst(img) 
    size := 12.0 // font size in pixels 
    pt := freetype.Pt(x, y+int(c.PointToFixed(size)>>6)) 

    if _, err := c.DrawString(label, pt); err != nil { 
     // handle error 
    } 
} 

如果你不想與freetype包和外部的字體文件麻煩,在font/basicfont包包含一個名爲Face7x13其圖形數據的基本字體是完全獨立的。這是你如何可以使用:

import (
    "golang.org/x/image/font" 
    "golang.org/x/image/font/basicfont" 
    "golang.org/x/image/math/fixed" 
    "image" 
    "image/color" 
) 

func addLabel(img *image.RGBA, x, y int, label string) { 
    col := color.RGBA{200, 100, 0, 255} 
    point := fixed.Point26_6{fixed.Int26_6(x * 64), fixed.Int26_6(y * 64)} 

    d := &font.Drawer{ 
     Dst: img, 
     Src: image.NewUniform(col), 
     Face: basicfont.Face7x13, 
     Dot: point, 
    } 
    d.DrawString(label) 
} 

這是本addLabel()功能如何使用:下面的代碼創建一個新的形象,借鑑了它的"Hello Go"文本和一個名爲hello-go.png文件並將其保存:

func main() { 
    img := image.NewRGBA(image.Rect(0, 0, 300, 100)) 
    addLabel(img, 20, 30, "Hello Go") 

    f, err := os.Create("hello-go.png") 
    if err != nil { 
     panic(err) 
    } 
    defer f.Close() 
    if err := png.Encode(f, img); err != nil { 
     panic(err) 
    } 
} 

注意上面的代碼也需要導入"image/png"包。請注意0​​座標是文字的底線。所以如果你想畫一條線到左上角,你必須使用x = 0y = 13(13是這個Face7x13字體的高度)。如果您願意,您可以通過從y座標中減去13來將其構建到addLabel()函數中,以便傳遞的y座標將成爲繪製文本的頂部座標。

還有在golang.org/x/image/font/inconsolata包定期和大膽的風格額外的自包含的字體,使用它們,您只需要指定不同的FaceaddLabel()

import "golang.org/x/image/font/inconsolata" 

     // To use regular Inconsolata font family: 
     Face: inconsolata.Regular8x16, 

     // To use bold Inconsolata font family: 
     Face: inconsolata.Bold8x16, 
+0

@sanmai查看編輯的答案,我提供了一個如何使用'basicfont.Face7x13'的例子。 – icza

+0

謝謝,就在這!只有它打印行[half cut](http://i.imgur.com/sPoxcAb.png) – sanmai

+0

@sanmai你的'img'足夠大嗎?可能是因爲您將文本放置在圖像底部下方而被剪切掉? – icza

3

這裏是示例代碼使用gg庫,我們已經有src.jpg或任何圖像,我們在它上面寫文字。你可以相應地調整畫布大小..這只是一個例子。讓我知道如果它不起作用。

package main 

import (
    "github.com/fogleman/gg" 
    "log" 
) 

func main() { 
    const S = 1024 
    im, err := gg.LoadImage("src.jpg") 
    if err != nil { 
     log.Fatal(err) 
    } 

    dc := gg.NewContext(S, S) 
    dc.SetRGB(1, 1, 1) 
    dc.Clear() 
    dc.SetRGB(0, 0, 0) 
    if err := dc.LoadFontFace("/Library/Fonts/Arial.ttf", 96); err != nil { 
     panic(err) 
    } 
    dc.DrawStringAnchored("Hello, world!", S/2, S/2, 0.5, 0.5) 

    dc.DrawRoundedRectangle(0, 0, 512, 512, 0) 
    dc.DrawImage(im, 0, 0) 
    dc.DrawStringAnchored("Hello, world!", S/2, S/2, 0.5, 0.5) 
    dc.Clip() 
    dc.SavePNG("out.png") 
} 
相關問題