2016-07-11 81 views
17

Dato image.RGBA, coordinate e una riga di testo, come si aggiunge un'etichetta semplice con un carattere fisso normale? Per esempio. Face7x13 da font/basicfont.Come aggiungere un'etichetta di testo semplice a un'immagine in 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? 
} 

L'allineamento non ha molta importanza, ma è meglio se potrei scrivere l'etichetta sopra una linea che inizia alle coordinate.

E vorrei evitare dipendenze esterne caricabili come i caratteri.

+0

Questo pacchetto afferma esplicitamente che fornisce solo un'interfaccia per i volti dei caratteri. '" Altri pacchetti forniscono implementazioni per i font. Ad esempio, un pacchetto TrueType ne fornisce uno basato su file .ttf. "' –

risposta

20

Il pacchetto golang.org/x/image/font definisce solo le interfacce per le facce dei caratteri e il disegno del testo sulle immagini.

È possibile utilizzare l'implementazione Go del rasterizzatore di font Freetype: github.com/golang/freetype.

Il tipo di chiave è freetype.Context, ha tutti i metodi necessari.

Per un esempio completo, controllare questo file: example/freetype/main.go. Questo esempio carica un file di font, crea e configura freetype.Context, disegna il testo sull'immagine e salva l'immagine del risultato nel file.

Supponiamo che il file del font sia già caricato e che sia configurato un contesto c (vedere l'esempio come farlo). Poi la funzione addLabel() potrebbe essere la seguente:

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 
    } 
} 

Se non si vuole complicarsi la vita con i file freetype pacchetto e di carattere esterno, il pacchetto font/basicfont contiene un carattere di base di nome Face7x13 i cui dati grafica è interamente autosufficiente . Questo è come si potrebbe usare che:

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) 
} 

Questo è come questa funzione addLabel() può essere utilizzato: il codice di seguito crea una nuova immagine, disegna il testo "Hello Go" su di esso e lo salva in un file chiamato 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) 
    } 
} 

Nota il codice sopra richiede anche l'importazione del pacchetto "image/png".

Si noti inoltre che la coordinata sarà la riga inferiore del testo. Quindi, se vuoi disegnare una linea nell'angolo in alto a sinistra, devi usare x = 0 e y = 13 (13 è l'altezza di questo font Face7x13). Se lo si desidera, è possibile creare tale funzione nella funzione addLabel() sottraendo 13 dalla coordinata , in modo che la coordinata passata sia la coordinata superiore a cui verrà disegnato il testo.

C'è anche un carattere autonomo aggiuntivo nella confezione golang.org/x/image/font/inconsolata con stile regolare e audace, di usarli, è necessario specificare solo un diverso Face in addLabel():

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 Vedi la risposta modificata, ho incluso un esempio su come usare 'basicfont.Face7x13'. – icza

+0

grazie, proprio per questo! Solo stampa le linee [mezzo taglio] (http://i.imgur.com/sPoxcAb.png) – sanmai

+0

@sanmai Il tuo 'img' supera abbastanza? Forse è tagliato perché posizioni il testo sotto la parte inferiore dell'immagine? – icza

3

Ecco il codice di esempio usando gg library dove abbiamo già src.jpg o qualsiasi immagine e scriviamo del testo su di esso .. puoi regolare la dimensione del canvas di conseguenza .. è solo un esempio. fammi sapere se non funziona.

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") 
} 
Problemi correlati