LED - Multilingual LED matrix output

It shouldn't be a problem in English-speaking countries, but some countries need to do some work in order to display their characters on LEDs. I am using DietPi OS installed on Raspberry Pi. And my native language is Korean, not English. In most cases, I use ssh on my PC to work on Raspberry Pi. And since the operating system of the PC is Korean Windows 10, there is no difficulty even if it happens to use Korean in Raspberry Pi. However, if you need to output Hangul(Korean language name) directly from Raspberry Pi, like LED output, you need to do some work. This content can be applied to Chinese and Japanese as well as Korean. Later I will show a sample using these languages.

Unicode font

To display the native language, you must first obtain a Unicode font that contains the native language.

Be Careful : Do not use the font of the Windows operating system without permission. There is a risk of copyright problems.

I will use Pan-CJK (China, Japan, Korea) Font made by Adobe and Google together. You are encouraged to obtain free Unicode fonts, including your native language.


This page contains an introduction to this font.


<https://theblog.adobe.com/new-pan-cjk-font-source-han-sans-2-0/>

Download the fonts at this site(https://github.com/adobe-fonts/source-han-sans/tree/release/OTF). On this site, Korean, Japanese, and Chinese Unicode fonts exist in various types such as bold, heavy, light, extralight, medium, normal, and regular types.

I downloaded these fonts and copied them to Raspberry Pi. I will use sans serif font. Since the LED matrix does not have a high resolution, using a serif body looks messy.

  • SourceHanSansJ-Regular.otf  (original name is SourceHanSans-Regular.otf. Why Japanese font doesn't use J symbol?)
  • SourceHanSansK-Regular.otf (Korean Regular font)
  • SourceHanSansSC-Regular.otf (Simplied Chinese Regular font)

I copied these files to the Raspberry Pi's /usr/local/src/font directory.

LED matrices

This time, four 64x32 sized LED matrices are connected horizontally to optimize for text play. The following preparations are required.

  • Raspberry Pi(3 or 4) with DietPi installed :1 EA
  • 64X32 LED matrices : 4 EA
  • RGB LED matrix HAT(Electrodragon HAT) : 1 EA
  • 5V 10A Power Supply : 1 EA
  • HUB75 cables :  4EA

The picture on the back is as follows.


S/W installation

Please refer to the following blogs for software installation.


And the otf2bdf tool is needed to convert the font downloaded earlier into a bitmap font. Font conversion is also explained in detail at https://github.com/hzeller/rpi-rgb-led-matrix/tree/master/fonts by Henner Zeller.


apt-get install -y otf2bdf 

Then, the TrueType font downloaded earlier is converted into a bitmap font.


otf2bdf -v -o SourceHanSansSC-Regular.bdf -r 72 -p 30 SourceHanSansSC-Regular.otf
otf2bdf -v -o SourceHanSansK-Regular.bdf -r 72 -p 30 SourceHanSansK-Regular.otf
otf2bdf -v -o SourceHanSansJ-Regular.bdf -r 72 -p 30 SourceHanSansJ-Regular.otf


Multilingual display on LED matrix

The following example code is based on runtext.py in the /rpi-rgb-led-matrix/bindings/python/samples directory.


import argparse
import time, os
from PIL import Image, ImageDraw 
from rgbmatrix import RGBMatrix, RGBMatrixOptions, graphics


parser = argparse.ArgumentParser(description='face match run')
parser.add_argument('--text', type=str, default='안녕하세요. 반갑습니다.')
parser.add_argument('--font', type=str, default='SourceHanSansK-Regular')
parser.add_argument('--R', type=int, default=255)
parser.add_argument('--G', type=int, default=255)
parser.add_argument('--B', type=int, default=0)
args = parser.parse_args()

color_R = max(0, min(args.R, 255))
color_G = max(0, min(args.G, 255))
color_B = max(0, min(args.B, 255))

myfont = '/usr/local/src/font/%s.bdf'%(args.font)

if os.path.exists(myfont) == False:
    print('Font[%s] Not found =>Use default[SourceHanSansK-Regular]'%(myfont))
    myfont = '/usr/local/src/font/SourceHanSansK-Regular.bdf'

options = RGBMatrixOptions()
options.cols = 64
options.rows = 32
options.chain_length =  4
options.parallel = 1
options.gpio_slowdown =  2
options.show_refresh_rate = 1
options.hardware_mapping = 'regular'  # I'm using Electrodragon HAT
matrix = RGBMatrix(options = options)

offscreen_canvas = matrix.CreateFrameCanvas()
font = graphics.Font()
font.LoadFont(myfont)
textColor = graphics.Color(color_R, color_G, color_B)
pos = offscreen_canvas.width
my_text = args.text

while True:
    offscreen_canvas.Clear()
    len = graphics.DrawText(offscreen_canvas, font, pos, 25, textColor, my_text)
    pos -= 1
    if (pos + len < 0):
        pos = offscreen_canvas.width

    time.sleep(0.05)
    offscreen_canvas = matrix.SwapOnVSync(offscreen_canvas)
<Bitmap font display example>

Since entering multiple languages ​​other than English in Raspberry Pi requires several cumbersome processes, the following commands were performed after accessing Raspberry Pi by remote SSH from a PC.
First, let's display Simplied Chinese sentences. The meaning of these sentences is as follows. "Hi, nice to meet you."



python3 runtext.py --font=SourceHanSansSC-Regular --text="你好很高兴认识你。"



Next Japanese.


python3 runtext.py --font=SourceHanSansJ-Regular --text="こんにちは。はじめまして。 " 



Finally Korean!


python3 runtext.py --font=SourceHanSansK-Regular --text="안녕하세요. 반갑습니다." 



TrueType Vs Bitmap Font

In the above example I used bitmap font. Let's look at the differences between bitmap fonts and TrueType fonts and how to use TrueType fonts. True type fonts maintain smooth lines regardless of the font size, whereas bitmap fonts have rough edges as if they are abusing low-resolution images.

However, when the resolution is low, very different results are obtained. If a TrueType font is used at a lower resolution as shown in the following figure, the color density of pixels passing through a part of the curve is lowered.

<True Type font on low resolution display>

Which of the two images below looks neat?
<low resolution characters using bitmap font and true type font>

At lower resolutions, bitmap fonts are often darker and clearer than TrueType fonts. However, if the resolution of the LED matrix is ​​moderately high or viewed from a distance, it may be more natural to use a truetype font.

Let's take a quick look at how to express multiple languages ​​using TrueType fonts. In this example, I will open a true type font(otf extension).  I intentionally doubled the image horizontal size for natural scrolling.



import argparse
import time, os
from PIL import Image, ImageDraw, ImageFont
from rgbmatrix import RGBMatrix, RGBMatrixOptions


parser = argparse.ArgumentParser(description='face match run')
parser.add_argument('--text', type=str, default='안녕하세요. 반갑습니다.')
parser.add_argument('--font', type=str, default='SourceHanSansK-Regular')
parser.add_argument('--R', type=int, default=255)
parser.add_argument('--G', type=int, default=255)
parser.add_argument('--B', type=int, default=0)
args = parser.parse_args()

color_R = max(0, min(args.R, 255))
color_G = max(0, min(args.G, 255))
color_B = max(0, min(args.B, 255))

myfont = '/usr/local/src/font/%s.otf'%(args.font)

if os.path.exists(myfont) == False:
    print('Font[%s] Not found =>Use default[SourceHanSansK-Regular]'%(myfont))
    myfont = '/usr/local/src/font/nanumgothic.otf'

img_width = 64 * 4 * 2
options = RGBMatrixOptions()
options.cols = 64
options.rows = 32
options.chain_length =  4
options.parallel = 1
options.gpio_slowdown =  2
options.show_refresh_rate = 1
options.hardware_mapping = 'regular'  # I'm using Electrodragon HAT
matrix = RGBMatrix(options = options)
offscreen_canvas = matrix.CreateFrameCanvas()

image = Image.new('RGB', (img_width, 32),(0, 0, 0))
draw = ImageDraw.Draw(image)
font = ImageFont.truetype(myfont, 25)
draw.text((0,0), args.text, font=font, fill=(color_R,color_G,color_B,0))

xpos = 0
while True:
    xpos += 1
    if (xpos > img_width):
        xpos = 0

    offscreen_canvas.SetImage(image, -xpos)
    offscreen_canvas.SetImage(image, -xpos + img_width)

    offscreen_canvas = matrix.SwapOnVSync(offscreen_canvas)
    time.sleep(0.01)
<Truetype font display example>

Run the code!


python3 runtext_image.py --font=SourceHanSansK-Regular --text="안녕하세요. 반갑습니다." 


<Truetype font display>

It is difficult to distinguish greatly in the photo, but if you test it yourself, you can see that the periphery of the text is slightly blurred. You can choose between bitmap font or true type font considering the display size and viewing distance you use.

Wrapping up

Users who do not speak English as their native language can display various languages ​​on the LED matrix as in the example above if you only need a Unicode-based multilingual font.

You can download the source codes at https://github.com/raspberry-pi-maker/IoT/tree/master/led%20-%20Multilingual%20LED%20matrix%20output



댓글

이 블로그의 인기 게시물

LED-12. Displaying HDMI Contents

LED - 5. Raspberry Pi 4 + DietPi Buster + Electrodragon HAT - Part 1

LED-11. Make a very big size 384 X 512 RGB Matrix #6(final)