Golang : Print UTF-8 fonts on image example




Problem:

You need to write UTF-8 characters such as Icelandic,Chinese, Japanese, Korean, Russian or symbols like © Ø ® ß ◊ ¥ Ô º ™ € ¢ ∞ § Ω on an image with Go. For cases such as using it as a label on a button. How to do that?

Solution:

Use the wqy-zenhei.ttf font and github.com/golang/freetype to draw the UTF-8 characters on the image.

Download the font from http://www.slackware.com/~alien/slackbuilds/wqy-zenhei-font-ttf/build/wqy-zenhei-0.4.23-1.tar.gz and extract the wqy-zenhei.ttf to the same folder as this program.

Run the code example that follows and view the output utf8text.png file with an image viewer.

Here you go!


 package main

 import (
  "bufio"
  "fmt"
  "image"
  "image/color"
  "image/draw"
  "image/png"
  "io/ioutil"
  "os"

  "github.com/golang/freetype"
  "github.com/golang/freetype/truetype"
 )

 var (
  backgroundWidth  = 650
  backgroundHeight = 150
  utf8FontFile = "wqy-zenhei.ttf"
  utf8FontSize = float64(15.0)
  spacing = float64(1.5)
  dpi = float64(72)
  ctx = new(freetype.Context)
  utf8Font = new(truetype.Font)
  red = color.RGBA{255, 0, 0, 255}
  blue = color.RGBA{0, 0, 255, 255}
  white = color.RGBA{255, 255, 255, 255}
  black = color.RGBA{0, 0, 0, 255}
  background *image.RGBA
  // more color at https://github.com/golang/image/blob/master/colornames/table.go
 )

 func main() {

  // download font from http://www.slackware.com/~alien/slackbuilds/wqy-zenhei-font-ttf/build/wqy-zenhei-0.4.23-1.tar.gz
  // extract wqy-zenhei.ttf to the same folder as this program

  // Read the font data - for this example, we load the Chinese fontfile wqy-zenhei.ttf,
  // but it will display any utf8 fonts such as Russian, Japanese, Korean, etc as well.
  // some utf8 fonts cannot be displayed. You need to use your own language .ttf file
  fontBytes, err := ioutil.ReadFile(utf8FontFile)
  if err != nil {
 fmt.Println(err)
 return
  }

  utf8Font, err = freetype.ParseFont(fontBytes)
  if err != nil {
 fmt.Println(err)
 return
  }

  fontForeGroundColor, fontBackGroundColor := image.NewUniform(black), image.NewUniform(white)

  background = image.NewRGBA(image.Rect(0, 0, backgroundWidth, backgroundHeight))

  draw.Draw(background, background.Bounds(), fontBackGroundColor, image.ZP, draw.Src)

  ctx = freetype.NewContext()
  ctx.SetDPI(dpi) //screen resolution in Dots Per Inch
  ctx.SetFont(utf8Font)
  ctx.SetFontSize(utf8FontSize) //font size in points
  ctx.SetClip(background.Bounds())
  ctx.SetDst(background)
  ctx.SetSrc(fontForeGroundColor)

  var UTF8text = []string{
 `English - Hello, Chinese - 你好, Russian - Здравствуйте, Korean - 여보세요, Greek - Χαίρετε`,
 `Tajik - Салом, Japanese - こんにちは, Icelandic - Halló, Belarusian - добры дзень`,
 `symbols - © Ø ® ß ◊ ¥ Ô º ™ € ¢ ∞ § Ω`,
  }

  // Draw the text to the background
  pt := freetype.Pt(10, 10+int(ctx.PointToFixed(utf8FontSize)>>6))

  // not all utf8 fonts are supported by wqy-zenhei.ttf
  // use your own language true type font file if your language cannot be printed

  for _, str := range UTF8text {
 _, err := ctx.DrawString(str, pt)
 if err != nil {
 fmt.Println(err)
 return
 }
 pt.Y += ctx.PointToFixed(utf8FontSize * spacing)
  }

  // Save
  outFile, err := os.Create("utf8text.png")
  if err != nil {
 fmt.Println(err)
 os.Exit(-1)
  }
  defer outFile.Close()
  buff := bufio.NewWriter(outFile)

  err = png.Encode(buff, background)
  if err != nil {
 fmt.Println(err)
 os.Exit(-1)
  }

  // flush everything out to file
  err = buff.Flush()
  if err != nil {
 fmt.Println(err)
 os.Exit(-1)
  }
  fmt.Println("Save to utf8text.png")

 }

NOTES:

Check out https://github.com/pbnjay/pixfont as well.

Not all languages fonts are available. See the readme section extracted from wqy-zenhei's README on language coverage.


 III. Language Coverage

  The following table is based on the locale data provided by fontconfig
  (generated by langcover.pl from Dejavu Project
  http://dejavu.sourceforge.net/wiki/index.php/Font_utilities).

 ZenHei 
  aa Afar 100% (62/62) 
  ab Abkhazia 75% (68/90) 
  af Afrikaans 100% (69/69) 
  am Amharic (0/264) 
  ar Arabic (0/125) 
  as (0/89) 
  ast Asturian 100% (72/72) 
  ava Avaric 100% (67/67) 
  ay Aymara 100% (60/60) 
  az Azerbaijani 85% (127/148) 
  az-ir  Azerbaijani in Iran (0/130) 
  ba Bashkir 78% (64/82) 
  bam Bambara 90% (54/60) 
  be Byelorussian 100% (68/68) 
  bg Bulgarian 100% (60/60) 
  bh Bihari (Devanagari script) (0/68) 
  bho Bhojpuri (Devanagari script) (0/68) 
  bi Bislama 100% (58/58) 
  bin Edo or Bini 92% (72/78) 
  bn Bengali (0/89) 
  bo Tibetan (0/95) 
  br Breton 100% (64/64) 
  bs Bosnian 85% (53/62) 
  bua Buriat (Buryat) 94% (66/70) 
  ca Catalan 100% (74/74) 
  ce Chechen 100% (67/67) 
  ch Chamorro 100% (58/58) 
  chm Mari (Lower Cheremis / Upper Cheremis) 86% (66/76) 
  chr Cherokee (0/85) 
  co Corsican 100% (85/85) 
  cs Czech 80% (66/82) 
  cu Old Church Slavonic 71% (74/103) 
  cv Chuvash 89% (66/74) 
  cy Welsh 87% (68/78) 
  da Danish 100% (70/70) 
  de German 100% (60/60) 
  dz Dzongkha (0/95) 
  el Greek 100% (70/70) 
  en English 100% (73/73) 
  eo Esperanto 81% (52/64) 
  es Spanish 100% (67/67) 
  et Estonian 93% (60/64) 
  eu Basque 100% (56/56) 
  fa Persian (0/129) 
  fi Finnish 93% (59/63) 
  fj Fijian 100% (52/52) 
  fo Faroese 100% (68/68) 
  fr French 100% (85/85) 
  ful Fulah (Fula) 87% (54/62) 
  fur Friulian 100% (66/66) 
  fy Frisian 100% (75/75) 
  ga Irish 77% (62/80) 
  gd Scots Gaelic 100% (70/70) 
  gez Ethiopic (Geez) (0/218) 
  gl Galician 100% (66/66) 
  gn Guarani 94% (66/70) 
  gu Gujarati (0/78) 
  gv Manx Gaelic 100% (54/54) 
  ha Hausa 86% (52/60) 
  haw Hawaiian 92% (58/63) 
  he Hebrew (0/27) 
  hi Hindi (Devanagari script) (0/68) 
  ho Hiri Motu 100% (52/52) 
  hr Croatian 85% (53/62) 
  hu Hungarian 94% (66/70) 
  hy Armenian (0/77) 
  ia Interlingua 100% (52/52) 
  ibo Igbo 89% (52/58) 
  id Indonesian 100% (54/54) 
  ie Interlingue 100% (52/52) 
  ik Inupiaq (Inupiak, Eskimo) 100% (68/68) 
  io Ido 100% (52/52) 
  is Icelandic 100% (70/70) 
  it Italian 100% (73/73) 
  iu Inuktitut (0/161) 
  ja Japanese 100% (6538/6538) 
  ka Georgian (0/33) 
  kaa Kara-Kalpak (Karakalpak) 84% (66/78) 
  ki Kikuyu 92% (52/56) 
  kk Kazakh 84% (65/77) 
  kl Greenlandic 95% (77/81) 
  km Khmer (0/70) 
  kn Kannada (0/80) 
  ko Korean 100% (2443/2443) 
  kok Kokani (Devanagari script) (0/68) 
  ks Kashmiri (Devanagari script) (0/68) 
  ku Kurdish 90% (58/64) 
  ku-ir  Kurdish in Iran (0/32) 
  kv Komi (Komi-Permyak/Komi-Siryan) 97% (68/70) 
  kw Cornish 89% (57/64) 
  ky Kirgiz 94% (66/70) 
  la Latin 83% (57/68) 
  lb Luxembourgish (Letzeburgesch) 100% (75/75) 
  lez Lezghian (Lezgian) 100% (67/67) 
  ln Lingala 90% (73/81) 
  lo Lao (0/65) 
  lt Lithuanian 75% (53/70) 
  lv Latvian 73% (57/78) 
  mg Malagasy 100% (56/56) 
  mh Marshallese 88% (55/62) 
  mi Maori 89% (57/64) 
  mk Macedonian 90% (38/42) 
  ml Malayalam (0/78) 
  mn Mongolian (0/130) 
  mo Moldavian 95% (122/128) 
  mr Marathi (Devanagari script) (0/68) 
  mt Maltese 91% (66/72) 
  my Burmese (Myanmar) (0/48) 
  nb Norwegian Bokmal 100% (70/70) 
  nds Low Saxon 100% (59/59) 
  ne Nepali (Devanagari script) (0/68) 
  nl Dutch 100% (83/83) 
  nn Norwegian Nynorsk 100% (76/76) 
  no Norwegian (Bokmal) 100% (70/70) 
  ny Chichewa 100% (54/54) 
  oc Occitan 100% (70/70) 
  om Oromo or Galla 100% (52/52) 
  or Oriya (0/79) 
  os Ossetic 100% (66/66) 
  pa Punjabi (Gurumukhi script) (0/63) 
  pl Polish 81% (57/70) 
  ps-af  Pashto in Afghanistan (0/49) 
  ps-pk  Pashto in Pakistan (0/49) 
  pt Portuguese 100% (83/83) 
  rm Rhaeto-Romance (Romansch) 100% (66/66) 
  ro Romanian 90% (56/62) 
  ru Russian 100% (66/66) 
  sa Sanskrit (Devanagari script) (0/68) 
  sah Yakut 86% (66/76) 
  sco Scots 92% (52/56) 
  se North Sami 89% (59/66) 
  sel Selkup (Ostyak-Samoyed) 100% (66/66) 
  sh Serbo-Croatian 100% (76/76) 
  si Sinhala (Sinhalese) (0/77) 
  sk Slovak 80% (69/86) 
  sl Slovenian 85% (53/62) 
  sm Samoan 100% (53/53) 
  sma South Sami 100% (60/60) 
  smj Lule Sami 100% (60/60) 
  smn Inari Sami 89% (61/68) 
  sms Skolt Sami 78% (63/80) 
  so Somali 100% (52/52) 
  sq Albanian 100% (56/56) 
  sr Serbian 100% (76/76) 
  sv Swedish 100% (68/68) 
  sw Swahili 100% (52/52) 
  syr Syriac (0/45) 
  ta Tamil (0/48) 
  te Telugu (0/80) 
  tg Tajik 84% (66/78) 
  th Thai (0/87) 
  ti-er  Eritrean Tigrinya (0/256) 
  ti-et  Ethiopian Tigrinya (0/282) 
  tig Tigre (0/221) 
  tk Turkmen 89% (66/74) 
  tl Tagalog (0/19) 
  tn Tswana 100% (56/56) 
  to Tonga 100% (53/53) 
  tr Turkish 92% (65/70) 
  ts Tsonga 100% (52/52) 
  tt Tatar 86% (66/76) 
  tw Twi 79% (58/73) 
  tyv Tuvinian 94% (66/70) 
  ug Uighur (0/125) 
  uk Ukrainian 97% (70/72) 
  ur Urdu (0/145) 
  uz Uzbek 88% (60/68) 
  ven Venda 83% (52/62) 
  vi Vietnamese 43% (85/194) 
  vo Volapuk 100% (54/54) 
  vot Votic 93% (58/62) 
  wa Walloon 100% (70/70) 
  wen Sorbian languages (lower and upper) 76% (58/76) 
  wo Wolof 100% (66/66) 
  xh Xhosa 100% (52/52) 
  yap Yapese 100% (58/58) 
  yi Yiddish (0/27) 
  yo Yoruba 77% (92/119) 
  zh-936 GBK Chinese national standard 100% (21921/21920)
  zh-cn  Chinese (simplified) 100% (6765/6765) 
  zh-hk  Chinese Hong Kong Supplementary Character Set 100% (2213/2213) 
  zh-mo  Chinese in Macau 100% (2213/2213) 
  zh-sg  Chinese in Singapore 100% (6765/6765) 
  zh-tw  Chinese (traditional) 100% (13063/13063)
  zu Zulu 100% (52/52) 

Happy coding!

References:

https://www.socketloop.com/tutorials/golang-how-to-print-rune-unicode-utf-8-and-non-ascii-cjk-chinese-japanese-korean-characters

https://github.com/golang/freetype/blob/master/example/freetype/main.go

https://godoc.org/github.com/golang/freetype

  See also : Golang : Put UTF8 text on OpenCV video capture image frame





By Adam Ng

IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.


Advertisement