Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
457 views
in Technique[技术] by (71.8m points)

python 2.7 - Drawing multilingual text using PIL and saving as 1-bit and 8-bit bitmaps

I started with the script in this nice answer. It works just fine for "RGB", but the 8-bit gray scale "L" and 1-bit black/white "1" PIL image modes just appear black. What am I doing wrong?

from PIL import Image, ImageDraw, ImageFont
import numpy as np

w_disp   = 128
h_disp   =  64
fontsize =  32
text     =  u"你好!"

for imtype in "1", "L", "RGB":
    image = Image.new(imtype, (w_disp, h_disp))
    draw  = ImageDraw.Draw(image)
    font  = ImageFont.truetype("/Library/Fonts/Arial Unicode.ttf", fontsize)
    w, h  = draw.textsize(text, font=font)
    draw.text(((w_disp - w)/2, (h_disp - h)/2), text, font=font)
    image.save("NiHao! 2 " + imtype + ".bmp")
    data = np.array(list(image.getdata()))
    print data.shape, data.dtype, "min=", data.min(), "max=", data.max()

Output:

(8192,) int64 min= 0 max= 0
(8192,) int64 min= 0 max= 0
(8192, 3) int64 min= 0 max= 255

imtype = "1": enter image description here

imtype = "L": enter image description here

imtype = "RGB": enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

UPDATE:

This answer suggests using PIL's Image.point() method instead of .convert().

The whole thing looks like this:

from PIL import Image, ImageDraw, ImageFont
import numpy as np
w_disp   = 128
h_disp   =  64
fontsize =  32
text     =  u"你好!"

imageRGB = Image.new('RGB', (w_disp, h_disp))
draw  = ImageDraw.Draw(imageRGB)
font  = ImageFont.truetype("/Library/Fonts/Arial Unicode.ttf", fontsize)
w, h  = draw.textsize(text, font=font)
draw.text(((w_disp - w)/2, (h_disp - h)/2), text, font=font)

image8bit = imageRGB.convert("L")
imageRGB.save("NiHao! RGB.bmp")
image8bit.save("NiHao! 8bit.bmp")

imagenice_80  = image8bit.point(lambda x: 0 if x < 80  else 1, mode='1')
imagenice_128 = image8bit.point(lambda x: 0 if x < 128 else 1, mode='1')
imagenice_80.save("NiHao! nice 1bit 80.bmp")
imagenice_128.save("NiHao! nice 1bit 128.bmp")

NiHao! RGB NiHao! 8 bit NiHao! 1 bit 80 NiHao! 1 bit 128


ORIGINAL:

It looks like the TrueType fonts do not want to work with anything less than RGB.

You can try down-converting the images using PIL's .convert() method.

Starting with the RGB image, this gives:

image.convert("L"): enter image description here

image.convert("1"): enter image description here

Converting to 8-bit gray scale works nicely, but starting with TrueType fonts, or any font that is based on a gray scale, a 1-bit conversion will always look rough.

For good looking 1-bit images, it is probably necessary to start with a 1-bit bitmapped Chinese font designed for digital on/off displays.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...