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.
See the previous post on how to handle fonts in PIL.
Run the code.
For the rainbow background color effect, I prepared some background images with rainbow patterns.
Run the code.
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.
You can download the source codes at https://github.com/raspberry-pi-maker/IoT/tree/master/led%20-%20various%20text%20effect
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 togetherimport 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
댓글
댓글 쓰기