LED - Text Effect

In a previous post, I showed you how to display a variety of non-English languages ​​on an LED matrix. In this post, I will look at displaying colorful text that has been image-processed on the LED, rather than just displaying simple text.
The image processing content introduced in this article is related to the previous post and https://opencvcooking.blogspot.com/2019/12/basic-cooking-2-pil-text.html.


Outline Text

Outline text is the text extracted from the outline of the font as shown in the following figure. gimp and other image editing tools make it easy to create outline text images. Let's see how to make it using PIL. In the previous OpenCV blog, the results of the processing were output to a computer screen or file, but this time to the LED matrix.

<Outline text Example>


See the previous post on how to handle fonts in PIL.


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


parser = argparse.ArgumentParser(description='text effect run')
parser.add_argument('--text', type=str, default='안녕하세요. 반갑습니다.')
parser.add_argument('--font', type=str, default='SourceHanSansK-Bold')
parser.add_argument('--R', type=int, default=255, help='linecolor of R')
parser.add_argument('--G', type=int, default=255, help='linecolor of R')
parser.add_argument('--B', type=int, default=0, help='linecolor of R')
parser.add_argument('--fR', type=int, default=0, help='fillcolor of R')
parser.add_argument('--fG', type=int, default=0, help='fillcolor of G')
parser.add_argument('--fB', type=int, default=0, help='fillcolor of B')
parser.add_argument('--t', type=int, default=1, help='thickness')
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))

f_R = max(0, min(args.fR, 255))
f_G = max(0, min(args.fG, 255))
f_B = max(0, min(args.fB, 255))
x_margin = 3
y_margin = -3
myfont = '/usr/local/src/font/%s.otf'%(args.font)

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

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

font = ImageFont.truetype(myfont, 25)
text_size = font.getsize(args.text)[0]
img_width = text_size + options.cols * options.chain_length
image = Image.new('RGB', (img_width, 32),(0, 0, 0))
draw = ImageDraw.Draw(image)



draw.text((x_margin - args.t, y_margin) ,args.text, font=font, fill=(color_R, color_G,color_B))
draw.text((x_margin + args.t, y_margin) ,args.text, font=font, fill=(color_R, color_G,color_B))
draw.text((x_margin, y_margin + args.t) ,args.text, font=font, fill=(color_R, color_G,color_B))
draw.text((x_margin, y_margin - args.t) ,args.text, font=font, fill=(color_R, color_G,color_B))
draw.text((x_margin, y_margin) ,args.text, font=font, fill=(f_R, f_G,f_B))

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

    offscreen_canvas.SetImage(image, -xpos)
    offscreen_canvas.SetImage(image, -xpos + img_width)
    offscreen_canvas = matrix.SwapOnVSync(offscreen_canvas)
    if(first == True):
        first = False
        time.sleep(1)    
    time.sleep(0.01)
time.sleep(1)


Run the code.



zroot@DietPi:/usr/local/src/lotto# python3 effect_outline.py



Text with background image

Use the AND operation of two images. Fill the text image with (255,255,255) and then AND the background image. Use PIL and OpenCV together


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



base_dir = '/usr/local/src'
parser = argparse.ArgumentParser(description='text effect run')
parser.add_argument('--text', type=str, default='안녕하세요. 반갑습니다. 좋은 날씨입니다.')
parser.add_argument('--font', type=str, default='SourceHanSansK-Bold')
parser.add_argument('--R', type=int, default=255, help='textcolor of R')
parser.add_argument('--G', type=int, default=255, help='textcolor of R')
parser.add_argument('--B', type=int, default=0, help='textcolor of R')
parser.add_argument('--image', type=str, default='%s/lotto/image/rainbow1.png'%(base_dir), help='background image')
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))

x_margin = 10
y_margin = -3
myfont = '%s/font/%s.otf'%(base_dir, args.font)

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

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

font = ImageFont.truetype(myfont, 25)
text_size = font.getsize(args.text)[0]
img_width = text_size + options.cols * options.chain_length

back_img = Image.open(args.image)
back_img = back_img.resize((img_width, 32))
mask = Image.new('RGBA', (img_width, 32),(0, 0, 0, 255))
draw = ImageDraw.Draw(mask)
fillcolor = (0,0,0,0)
draw.text((x_margin, y_margin), args.text, font=font, fill=fillcolor)
back_img.paste(mask, (0, 0), mask)
# back_img.save("/tmp/out.jpg")


xpos = 0
first = True
while True:
    xpos += 1
    if (xpos > (text_size + x_margin + 1)):
        break

    offscreen_canvas.SetImage(back_img, -xpos)
    offscreen_canvas.SetImage(back_img, -xpos + img_width)
    offscreen_canvas = matrix.SwapOnVSync(offscreen_canvas)
    if(first == True):
        first = False
        time.sleep(1)

    time.sleep(0.01)
time.sleep(1)


For the rainbow background color effect, I prepared some background images with rainbow patterns.

<rainbow2.png>

Run the code.


root@DietPi:/usr/local/src/lotto# python3 effect_backgroundimage.py --image="./image/rainbow2.png"


You will see gorgeous text like the following picture. If you look at the actual LED, not the picture, you can feel the rainbow color more clearly.


Wrapping up

Using the Python PIL, various font and image processing effects can be applied to the LED. Unfortunately, in OpenCV, font usage is more limited than PIL. Therefore, it is recommended to use PIL when you need to use fonts. In the next post, I will show you how to manage your various LED matrix Python examples in a GUI environment.

You can download the source codes at https://github.com/raspberry-pi-maker/IoT/tree/master/led%20-%20various%20text%20effect


댓글

이 블로그의 인기 게시물

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)