15

I would like to add Russian text to the image. I use PIL 1.1.7 and Python 2.7 on Windows machine. Since PIL compiled without libfreetype library, I use the following on development server:

font_text = ImageFont.load('helvR24.pil')
draw.text((0, 0), 'Текст на русском', font=font_text)

(helvR24.pil is taken from http://effbot.org/media/downloads/pilfonts.zip)

On Production environment I do the following:

font_text = ImageFont.truetype('HelveticaRegular.ttf', 24, encoding="utf-8")
draw.text((0, 0), 'Текст на русском', font=font_text)

(tried to use unic, cp-1251 instead of utf-8)

In both cases it doesn't display Russian characters ('squares' or dummy characters are displayed instead). I think it doesn't work on Development environment since most probably helvR24.pil doesn't contain Russian characters (don't know how to check it). But HelveticaRegular.ttf surely has it. I also checked that my .py file has геа-8 encoding. And it doesn't display Russian characters even with default font:

draw.text((0, 0), 'Текст на русском', font=ImageFont.load_default())

What else should I try / verify? I've looked thru https://stackoverflow.com/a/18729512/604388 - it doesn't help.

Community
  • 1
  • 1
LA_
  • 19,823
  • 58
  • 172
  • 308
  • try to pass the text as unicode string: `draw.text((0, 0), u'Текст на русском', font=ImageFont.load_default())` – mata Sep 22 '13 at 10:52
  • @mata, surely I've tried that already (as well as `unicode('Текст на русском', 'utf-8')`). It returns `UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)` referring to `PIL\ImageDraw.py", line 267, text mask = font.getmask(text, self.fontmode)`. – LA_ Sep 22 '13 at 12:05

2 Answers2

17

I had a similar issue and solved it.

There are a couple things you have to be careful about:

  1. Ensure that your strings are interpreted as unicode, either by importing unicode_literarls from _____future_____ or by prepending the u to your strings
  2. Ensure you are using a font that is unicode,there are some free here: open-source unicode typefaces I suggest this: dejavu

here is the code:

#!/usr/bin/python
# -*- coding: utf-8 -*-
from PIL import Image, ImageDraw, ImageFont, ImageFilter

#configuration
font_size=36
width=500
height=100
back_ground_color=(255,255,255)
font_size=36
font_color=(0,0,0)
unicode_text = u"\u2605" + u"\u2606" + u"Текст на русском"

im  =  Image.new ( "RGB", (width,height), back_ground_color )
draw  =  ImageDraw.Draw ( im )
unicode_font = ImageFont.truetype("DejaVuSans.ttf", font_size)
draw.text ( (10,10), unicode_text, font=unicode_font, fill=font_color )

im.save("text.jpg")

here is the results

enter image description here

JackNova
  • 3,911
  • 5
  • 31
  • 49
  • 1
    I've created a [script that draws all Unicode characters based on your answer](https://gist.github.com/zed/07a8175ba07f393a6004/83e59f794e9d746384e2c23fda4aad959730a104#file-text2image-py) – jfs Jan 28 '15 at 15:39
4

Can you examine your TTF file? I suspect that it doesn't support the characters you want to draw.

On my computer (Ubuntu 13.04), this sequence produces the correct image:

ttf=ImageFont.truetype('/usr/share/fonts/truetype/msttcorefonts/Arial.ttf', 16)

im = Image.new("RGB", (512,512), "white")
ImageDraw.Draw(im).text((00,00), u'Текст на русском', fill='black', font=ttf)

im.show()

N.b. When I didn't specify unicode (u'...'), the result was mojibake.

Robᵩ
  • 163,533
  • 20
  • 239
  • 308