2015-03-11 1 views
13

È l'unico modo per disegnare una forma in Go con una larghezza della linea per farlo con le primitive pixel per pixel?Disegna un rettangolo in Golang?

Desidero disegnare un'etichetta con pochi rettangoli e codici a barre, generare e generare un PNG/PDF.

+1

Non ho provato questi, ma https://code.google.com/p/rog-go/source/browse/canvas/ e https://code.google.com/p/draw2d/ potrebbe aiutare . – twotwotwo

+0

grazie guardato draw2d. scaricato ma ha incontrato un sacco di problemi di compilazione (sono su stack appengine). molto lavoro per iniziare. il caso peggiore proverà a risolverli. – Fakeer

+0

lol chi era offensivo il requisito di tracciare una linea che la domanda è stata downvoted! – Fakeer

risposta

27

La libreria standard Go non offre funzionalità di disegno o pittura primitive.

Ciò che fornisce sono i modelli per i colori (pacchetto image/color) e un'interfaccia Image con diverse implementazioni (pacchetto image). Il post del blog The Go Image package è una buona introduzione a questo.

Fornisce inoltre la capacità di combinare le immagini (ad esempio disegnarle l'una sull'altra) con diverse operazioni nel pacchetto image/draw. Questo può essere usato molto più di quanto possa sembrare all'inizio. C'è un bel articolo del blog sul pacchetto image/draw che mette in mostra alcune delle sue potenzialità: The Go image/draw package

Un altro esempio è il gioco open-source Gopher's Labyrinth (divulgazione: Sono l'autore) che ha un interfaccia grafica e utilizza nient'altro solo la libreria standard di Go per assemblare la sua vista.

Gopher's Labyrinth Screenshot

E 'open source, controlla le sue fonti come è fatto. Ha una visuale di gioco scorrevole con immagini/animazioni in movimento.

La libreria standard supporta anche la lettura e la scrittura di formati immagine più comuni come GIF, JPEG, PNG, e il supporto per altri formati sono disponibili fuori dalla scatola: BMP, RIFF, TIFF e anche WEBP (solo un lettore/decodificatore).

Sebbene il supporto non sia fornito dalla libreria standard, è abbastanza semplice disegnare linee e rettangoli su un'immagine. Data un'immagine img che supporta cambiare un pixel con un metodo: Set(x, y int, c color.Color) (per esempio image.RGBA è perfetto per noi) e un col di tipo color.Color:

// HLine draws a horizontal line 
func HLine(x1, y, x2 int) { 
    for ; x1 <= x2; x1++ { 
     img.Set(x1, y, col) 
    } 
} 

// VLine draws a veritcal line 
func VLine(x, y1, y2 int) { 
    for ; y1 <= y2; y1++ { 
     img.Set(x, y1, col) 
    } 
} 

// Rect draws a rectangle utilizing HLine() and VLine() 
func Rect(x1, y1, x2, y2 int) { 
    HLine(x1, y1, x2) 
    HLine(x1, y2, x2) 
    VLine(x1, y1, y2) 
    VLine(x2, y1, y2) 
} 

Usando queste semplici funzioni qui è un programma esempio eseguibile che disegna una linea e un rettangolo e salva l'immagine in un file .png:

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

var img = image.NewRGBA(image.Rect(0, 0, 100, 100)) 
var col color.Color 

func main() { 
    col = color.RGBA{255, 0, 0, 255} // Red 
    HLine(10, 20, 80) 
    col = color.RGBA{0, 255, 0, 255} // Green 
    Rect(10, 10, 80, 50) 

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

Se si vuole disegnare testi, è possibile utilizzare il Go implementation of FreeType. Verificate anche questa domanda per una semplice introduzione a stringhe di disegno sulle immagini: How to add a simple text label to an image in Go?

Se si desidera utilizzare funzionalità avanzate e più complesse di disegno, ci sono anche many external libraries disponibili, ad esempio:

http://github.com/llgcode/draw2d/

+2

icza molte grazie. ho visto le strutture pkg dell'immagine. semplicemente non è possibile "connettere i punti" e trovare qualcosa di simile a quello che si sta facendo in hline e vline. questo è qualcosa che non volevo fare perché gli algoritmi di riga non sono semplici con l'anti-aliasing della rasterizzazione, bresenham ecc. Proverò il tuo esempio ora e imparerò. e grazie anche per aver suggerito freetype - mettere il testo sull'etichetta era anche parte del mio req che ho dimenticato di porre nella domanda. – Fakeer

+1

icza necklace game btw. perché non utilizzarlo gratuitamente su Appengine? – Fakeer

+0

@Fakeer Perché non è AppEngine e la produzione è pronta. Il gioco è stato creato in meno di 48 ore (regole Gopher Gala). Quindi questo è più simile a una demo e non quanto sarebbe bello se ci si dedicasse più tempo. – icza

0

mio niubbo sparato a disegnare un rettangolo di spessore della linea dato. Ancora primitivo

func Rect(x1, y1, x2, y2, thickness int, img *image.RGBA) { 
    col := color.RGBA{0, 0, 0, 255} 

    for t:=0; t<thickness; t++ { 
     // draw horizontal lines 
     for x := x1; x<= x2; x++ { 
      img.Set(x, y1+t, col) 
      img.Set(x, y2-t, col) 
     } 
     // draw vertical lines 
     for y := y1; y <= y2; y++ { 
      img.Set(x1+t, y, col) 
      img.Set(x2-t, y, col) 
     } 
    } 
} 


// handler to test 
func draw(w http.ResponseWriter, r *http.Request) { 
    img := image.NewRGBA(image.Rect(0, 0, 1200, 1800)) 
    Rect(5, 5, 1195, 1795, 2, img) 
    png.Encode(w, img) 
} 
4

Probabilmente stai cercando il pacchetto draw2d.Dal loro github readme:

Operazioni in draw2d includono poligoni carezze e di riempimento, archi, curve di Bézier, immagini di disegno e rendering del testo con i font TrueType. Tutte le operazioni di disegno possono essere trasformate da trasformazioni affini (scala, rotazione, traduzione).

Il seguente codice disegna un rettangolo nero e lo scrive in un file .png. Sta usando la versione v1 (go get -u github.com/llgcode/draw2d).

package main 

import (
     "github.com/llgcode/draw2d/draw2dimg" 

     "image" 
     "image/color" 
) 

func main() { 
     i := image.NewRGBA(image.Rect(0, 0, 200, 200)) 
     gc := draw2dimg.NewGraphicContext(i) 
     gc.Save() 
     gc.SetStrokeColor(color.Black) 
     gc.SetFillColor(color.Black) 
     draw2d.Rect(gc, 10, 10, 100, 100) 
     gc.FillStroke() 
     gc.Restore() 

     draw2dimg.SaveToPngFile("yay-rectangle.png", i) 
} 

Si prega di consultare the github page per la versione più recente.

+0

Non riesco a capire perché tutti pubblichino questo esempio rotto. Il pacchetto draw2d non contiene NewGraphicContext e SaveToPngFile. Se si tenta di eseguire questo codice, si ottiene qualcosa come ". \ Generate.go: 13: undefined: draw2d.NewGraphicContext" Entrambe le funzioni si trovano all'interno di github.com/llgcode/draw2d/draw2dimg. –

+0

L'esempio sulla pagina github è cambiato. Ho aggiornato il mio codice per utilizzare la nuova versione –

+0

Penso che NewGraphicContext prenda draw.Image giusto? image.Image non ha la funzione "set()". –

1

Ecco come disegnare due rettangoli utilizzando le librerie golang standard di

// https://blog.golang.org/go-imagedraw-package 

package main 

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

func main() { 

    new_png_file := "/tmp/two_rectangles.png" 

    myimage := image.NewRGBA(image.Rect(0, 0, 220, 220)) 
    green := color.RGBA{0, 100, 0, 255} 

    // backfill entire surface with green 
    draw.Draw(myimage, myimage.Bounds(), &image.Uniform{green}, image.ZP, draw.Src) 

    red_rect := image.Rect(60, 80, 120, 160) // geometry of 2nd rectangle 
    myred := color.RGBA{200, 0, 0, 255} 

    // create a red rectangle atop the green surface 
    draw.Draw(myimage, red_rect, &image.Uniform{myred}, image.ZP, draw.Src) 

    // ... save image 

    myfile, _ := os.Create(new_png_file) 
    png.Encode(myfile, myimage) 
} 

sopra genererà un file PNG con i nostri due rettangoli:

enter image description here

0

Mentre il tempo è passato, non sembra sii una bella nuova libreria chiamata Go Graphics (gg). Sembra simile al noto draw2d, ma sembra essere più popolare.