2015-03-17 19 views
13

Tôi đang cố gắng hiển thị một số văn bản trên png trong một dự án Golang bằng cách sử dụng freetype/truetype. Như bạn có thể thấy từ phần đính kèm, tôi đang cố gắng hiển thị 4 chữ cái trong các cột - mỗi chữ cái được định tâm trong cột. Đã sử dụng api truetype để có được giới hạn và chiều rộng của glyphs nhưng đã không thể chuyển đổi chúng để cung cấp cho tôi một bù đắp chính xác cho mỗi glyph. Ví dụ: với phông chữ O glyph, cho phông chữ tôi sử dụng. Tôi nhận được các kích thước sau:Căn chỉnh văn bản trong golang với Truetype

Hmetric {AdvanceWidth:543 LeftSideBearing:36} Bounds {XMin:0 YMin:-64 XMax:512 YMax:704} Advance width: 512

Với kích thước cuối cùng được trả lại từ GlyphBuf.

tôi trả lại nó bằng cách sử dụng sau đây:

size := 125.00 tileOffset := (int(tileWidth) * i) + int(tileWidth/2) pt := freetype.Pt(tileOffset, (imgH-newCharHeight)-int(size))

Làm thế nào tôi có thể sử dụng các kích thước hình tượng được trả về bởi truetype để bù đắp các chữ cái một cách chính xác? Tôi đã thử sử dụng mã số AdvanceWidth như chi tiết in this plotinum (dòng 160) nhưng điều đó không cho tôi kết quả nhất quán trên tất cả các hình tượng.

Example of rendering

+1

Heh ... hoạt kê đủ, chúng tôi đang tìm kiếm tại đây tại công việc của tôi tuần trước. Mỗi phông chữ có tính chất đi lên và gốc ... nhô ra/nhô ra, vv Về cơ bản, bạn cần một API cung cấp cho bạn kích thước mà không cần đi lên .. để bạn có thể định vị nó đúng cách. Có một cách chơi với phương thức 'Extents' trong API đó và các thuộc tính Ascent và Descent. Tôi sẽ cung cấp một câu trả lời đúng khi tôi nghỉ ngơi hôm nay –

+1

Apoplogies - thuật ngữ của tôi là tắt - Ascent và Descent liên quan đến định vị dọc .. những gì bạn cần là Advance hoặc Bounds của mỗi nhân vật. Tôi không cho rằng bạn có thể chia sẻ một đoạn đầy đủ bằng cách sử dụng 'AdvanceWidth'? –

Trả lời

8

Theo đề nghị của Simon giải pháp đúng là sử dụng AdvanceWidth:

enter image description here

thô dụ:

package main 

import (
    "flag" 
    "fmt" 
    "io/ioutil" 
    "log" 
    "image" 
    "bufio" 
    "image/draw" 
    "image/png" 
    "image/color" 
    "github.com/golang/freetype/truetype" 
    "golang.org/x/image/font" 
    "github.com/golang/freetype" 
    "os" 
) 

var (
    dpi  = flag.Float64("dpi", 72, "screen resolution in Dots Per Inch") 
    fontfile = flag.String("fontfile", "/usr/share/fonts/liberation/LiberationSerif-Regular.ttf", "filename of the ttf font") 
    hinting = flag.String("hinting", "none", "none | full") 
    size  = flag.Float64("size", 125, "font size in points") 
    spacing = flag.Float64("spacing", 1.5, "line spacing (e.g. 2 means double spaced)") 
    wonb  = flag.Bool("whiteonblack", false, "white text on a black background") 
    text  = string("JOJO") 
) 


func main() { 
    flag.Parse() 
    fmt.Printf("Loading fontfile %q\n", *fontfile) 
    b, err := ioutil.ReadFile(*fontfile) 
    if err != nil { 
     log.Println(err) 
     return 
    } 
    f, err := truetype.Parse(b) 
    if err != nil { 
     log.Println(err) 
     return 
    } 

    // Freetype context 
    fg, bg := image.Black, image.White 
    rgba := image.NewRGBA(image.Rect(0, 0, 1000, 200)) 
    draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src) 
    c := freetype.NewContext() 
    c.SetDPI(*dpi) 
    c.SetFont(f) 
    c.SetFontSize(*size) 
    c.SetClip(rgba.Bounds()) 
    c.SetDst(rgba) 
    c.SetSrc(fg) 
    switch *hinting { 
    default: 
     c.SetHinting(font.HintingNone) 
    case "full": 
     c.SetHinting(font.HintingFull) 
    } 

    // Make some background 

    // Draw the guidelines. 
    ruler := color.RGBA{0xdd, 0xdd, 0xdd, 0xff} 
    for rcount := 0; rcount < 4; rcount ++ { 
     for i := 0; i < 200; i++ { 
      rgba.Set(250*rcount, i, ruler) 
     } 
    } 

    // Truetype stuff 
    opts := truetype.Options{} 
    opts.Size = 125.0 
    face := truetype.NewFace(f, &opts) 


    // Calculate the widths and print to image 
    for i, x := range(text) { 
     awidth, ok := face.GlyphAdvance(rune(x)) 
     if ok != true { 
      log.Println(err) 
      return 
     } 
     iwidthf := int(float64(awidth)/64) 
     fmt.Printf("%+v\n", iwidthf) 

     pt := freetype.Pt(i*250+(125-iwidthf/2), 128) 
     c.DrawString(string(x), pt) 
     fmt.Printf("%+v\n", awidth) 
    } 


    // Save that RGBA image to disk. 
    outFile, err := os.Create("out.png") 
    if err != nil { 
     log.Println(err) 
     os.Exit(1) 
    } 
    defer outFile.Close() 
    bf := bufio.NewWriter(outFile) 
    err = png.Encode(bf, rgba) 
    if err != nil { 
     log.Println(err) 
     os.Exit(1) 
    } 
    err = bf.Flush() 
    if err != nil { 
     log.Println(err) 
     os.Exit(1) 
    } 
    fmt.Println("Wrote out.png OK.") 


} 
+0

Có thể trong Go để tính toán Hình chữ nhật/Gốc hoặc Hình chữ nhật bị ràng buộc cho một chuỗi được hiển thị bằng phông chữ đúng không? – Aaron

+0

Cảm ơn ví dụ tốt. Bạn có thể giải thích hai dòng này: 'iwidthf: = int (float64 (awidth)/64)' và 'pt: = freetype.Pt (i * 250 + (125-iwidthf/2), 128)' - là gì hằng số ở đó? – kirhgoff

Các vấn đề liên quan