NeoWang
NeoWang

Reputation: 18513

How I can load a font file with PIL.ImageFont.truetype without specifying the absolute path?

When I write the code in Windows, this code can load the font file just fine:

ImageFont.truetype(filename='msyhbd.ttf', size=30);

I guess the font location is registered in Windows registry. But when I move the code to Ubuntu, and copy the font file over to /usr/share/fonts/, the code cannot locate the font:

 self.font = core.getfont(font, size, index, encoding)
 IOError: cannot open resource

How can I get PIL to find the ttf file without specifying the absolute path?

Upvotes: 50

Views: 128973

Answers (8)

Kasan
Kasan

Reputation: 1

from PIL import Image, ImageDraw, ImageFont

# Function to create an image with a handwritten style table
def create_handwritten_table(data, image_name):
    # Image size setup
    image_width = 1400
    row_height = 100  # Adjust for handwriting style
    header_height = 120
    num_rows = len(data)
    image_height = header_height + row_height * (num_rows - 1)
    padding = 20
    
    # Load handwritten style font (placeholder font path)
    font_path = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"  # Replace with a handwritten font if available
    font_size = 24
    font = ImageFont.truetype(font_path, font_size)
    
    # Colors
    header_color = (240, 240, 240)
    row_color = (255, 255, 255)
    line_color = (0, 0, 0)
    text_color = (0, 0, 0)

    # Create an image
    image = Image.new("RGB", (image_width, image_height), "white")
    draw = ImageDraw.Draw(image)
    
    # Draw table headers
    headers = ["Seiten", "Prozessbeteiligte/r-Hauptfiguren", "Inhalt", "Zentrale Aussage(n)", "Meine Reaktion/Fragen"]
    column_widths = [100, 300, 400, 300, 300]
    
    # Draw header row
    x = 0
    for i, header in enumerate(headers):
        draw.rectangle([x, 0, x + column_widths[i], header_height], fill=header_color, outline=line_color)
        draw.text((x + padding, header_height // 3), header, fill=text_color, font=font)
        x += column_widths[i]
    
    # Draw table content with a handwritten style
    y = header_height
    for row in data[1:]:
        x = 0
        for i, cell in enumerate(row):
            draw.rectangle([x, y, x + column_widths[i], y + row_height], fill=row_color, outline=line_color)
            draw.text((x + padding, y + 20), cell, fill=text_color, font=font)
            x += column_widths[i]
        y += row_height
    
    # Save the image
    image.save(image_name)

# Data extracted from the provided images
table_data = [
    ["Seiten", "Prozessbeteiligte/r-Hauptfiguren", "Inhalt", "Zentrale Aussage(n)", "Meine Reaktion/Fragen"],
    ["Erster Akt", "Vorsitzender", "Begrüßung der Zuschauer und Erläuterung des Vorgehens.", 
     "„Wir – als Zuschauer – sind diejenigen, die urteilen werden.“", 
     "Warum sollen die Zuschauer des Gerichtsprozesses das Urteil treffen?"],
    ["9-13", "Vorsitzender, Verteidiger, Angeklagter (Lars Koch)", 
     "Feststellende Formalitäten, v.a. zu anwesenden Personen; Feststellung der Personalien Lars Kochs.", 
     "„Die Bundeswehr wartete mit der Entscheidung, das Ziel endgültig von oben wegzunehmen.“", 
     "Wie hat sich Lars Koch gefühlt bei der ganzen Frage?"],
    ["13-14", "Vorsitzender, Verteidiger, Staatsanwältin", 
     "Mit der Diskussion hat es begonnen. Lars Koch wird befragt, wann er die Tat begangen hat.", 
     "„Die Wahrheit muss ans Licht kommen!“", 
     "Bereut Lars die Tat wirklich oder ist die Frage dazu bedeutend?"],
    ["16-91", "Angeklagter, Vorsitzender, Verteidiger", 
     "Die wichtigen Fragen handeln von „Moral“ und „Recht.“", 
     "Darf ein Mensch getötet werden, um viele andere zu retten?", 
     "Ist er so verzweifelt, dass er keine andere Wahl hatte?"],
    ["28-50", "Staatsanwältin, Lars Koch", 
     "Es wird besprochen, warum er gehandelt hat.", 
     "„Ich musste nicht, was ich tue. Ich wollte die Menschen im Stadion retten!“", 
     "Hätte Lars Koch auch anders reagieren können, indem er wartet oder schreibt?"],
    ["51-62", "Vorsitzende, Verteidiger, Staatsanwältin", 
     "Es wird über die Menschenwürde und die Gesetze diskutiert.", 
     "„Das Leben eines Menschen ist nicht mehr wert als das andere.“", 
     "Verstehen die Zuschauer/Leser das Handeln oder nicht?"],
    ["63-76", "Herr Lauterbach, Lars Koch, Staatsanwältin, Frau Meiser", 
     "Zeugen erzählen von ihren Erfahrungen.", 
     "„Ich hatte solche Angst. Alle wussten nicht, was passiert.“", 
     "Wie reagieren die Leute, wenn sie hören, dass Lars Koch selbst Angst hatte?"],
    ["76-87", "Staatsanwältin, Lars Koch, Vorsitzende", 
     "Er wird immer noch befragt. War sein Handeln richtig?", 
     "„Ich musste es tun, sonst wären andere gestorben.“", 
     "Wie würden andere in so einer Situation handeln?"],
    ["98-113", "Vorsitzender, Verteidiger, Publikum", 
     "Der Verteidiger ist fertig. Jetzt sind die anderen gefragt.", 
     "„Jetzt liegt die Entscheidung bei Ihnen.“", 
     "Wie werden die anderen sich entscheiden?"],
    ["113-123", "Staatsanwältin, Verteidiger, Vorsitzender", 
     "Alles wird zusammengefasst.", 
     "„Das Gesetz ist klar, kein Platz für Gefühle.“", 
     "Stimmt das, was im Gesetz steht? Macht es Sinn?"],
    ["124-130", "Staatsanwältin, Verteidiger", 
     "Staatsanwältin und Verteidiger sagen beide, was sie halten.", 
     "„Manchmal muss man entscheiden, welches das kleinere Übel ist.“", 
     "/"],
    ["130FF", "Publikum, Vorsitzender", 
     "Das Publikum wird gebeten, eine Entscheidung zu treffen.", 
     "„Das Urteil liegt in Ihrer Hand!“", 
     "Was, wenn man nicht klar entscheiden kann, ob es richtig oder falsch war?"],
    ["131-140", "Publikum, Staatsanwältin, Verteidiger", 
     "Meinungen werden festgestellt.", 
     "„Es gibt keine einfache Antwort auf diese Frage.“", 
     "Was denken die Zuschauer/Leser? Wie fühlen sie sich dabei?"],
    ["141-145", "Publikum, Vorsitzender", 
     "Das ganze Vorgehen kommt zum Schluss.", 
     "„Was heißt Gerechtigkeit für uns?“", 
     "/"]
]

# Generate handwritten style table
handwritten_table_path = "/mnt/data/handwritten_table_image.png"
create_handwritten_table(table_data, handwritten_table_path)

# Return the handwritten table image path
handwritten_table_path

Upvotes: 0

Ian Barlow
Ian Barlow

Reputation: 1

In Debian, this allows you to load a .ttf or .otf font from the same directory as your Python script without having to specify the path:

custom_font = os.path.abspath(os.path.join(os.path.dirname(__file__), 'NameOfFont.ttf'))

Upvotes: 0

PythonProgrammi
PythonProgrammi

Reputation: 23443

To me worked this on xubuntu:

from PIL import Image,ImageDraw,ImageFont

# sample text and font
unicode_text = u"Hello World!"
font = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeMono.ttf", 28, encoding="unic")

# get the line size
text_width, text_height = font.getsize(unicode_text)

# create a blank canvas with extra space between lines
canvas = Image.new('RGB', (text_width + 10, text_height + 10), "orange")

# draw the text onto the text canvas, and use blue as the text color
draw = ImageDraw.Draw(canvas)
draw.text((5,5), u'Hello World!', 'blue', font)

# save the blank canvas to a file
canvas.save("unicode-text.png", "PNG")
canvas.show()

enter image description here

Windows version

from PIL import Image, ImageDraw, ImageFont

unicode_text = u"Hello World!"
font = ImageFont.truetype("arial.ttf", 28, encoding="unic")
text_width, text_height = font.getsize(unicode_text)
canvas = Image.new('RGB', (text_width + 10, text_height + 10), "orange")
draw = ImageDraw.Draw(canvas)
draw.text((5, 5), u'Hello World!', 'blue', font)
canvas.save("unicode-text.png", "PNG")
canvas.show()

The output is the same as above:

enter image description here

Upvotes: 58

kcp
kcp

Reputation: 77

In Windows 10 while using Visual code, i had to do as below to make it work.

font = ImageFont.truetype(os.environ['LOCALAPPDATA'] + "/Microsoft/Windows/Fonts/Dance Floor.ttf", 10)

Upvotes: 0

Harry Moreno
Harry Moreno

Reputation: 11603

On Mac I had some fonts in the project dependencies

$ find . -name *.ttf*
./venv/lib/python3.7/site-packages/werkzeug/debug/shared/ubuntu.ttf
./venv/lib/python3.7/site-packages/reportlab/fonts/Vera.ttf
./venv/lib/python3.7/site-packages/reportlab/fonts/VeraBI.ttf
./venv/lib/python3.7/site-packages/reportlab/fonts/VeraBd.ttf
./venv/lib/python3.7/site-packages/reportlab/fonts/VeraIt.ttf

so I passed in Vera like so

font = ImageFont.truetype(r'./venv/lib/python3.7/site-packages/reportlab/fonts/Vera.ttf', 50)

you can also get a font like this but the size was too small

font = ImageFont.load_default()

Upvotes: 1

Ale
Ale

Reputation: 997

There is a Python fontconfig package, whereby one can access system font configuration, The code posted by Jeeg_robot can be changed like so:

from PIL import Image,ImageDraw,ImageFont
import fontconfig

# find a font file
fonts = fontconfig.query(lang='en')
for i in range(1, len(fonts)):
    if fonts[i].fontformat == 'TrueType':
        absolute_path = fonts[i].file
        break

# the rest is like the original code:
# sample text and font
unicode_text = u"Hello World!"
font = ImageFont.truetype(absolute_path, 28, encoding="unic")

# get the line size
text_width, text_height = font.getsize(unicode_text)

# create a blank canvas with extra space between lines
canvas = Image.new('RGB', (text_width + 10, text_height + 10), "orange")

# draw the text onto the text canvas, and use black as the text color
draw = ImageDraw.Draw(canvas)
draw.text((5,5), u'Hello World!', 'blue', font)

# save the blank canvas to a file
canvas.save("unicode-text.png", "PNG")
canvas.show()

Upvotes: 6

Rick
Rick

Reputation: 7506

On mac, I simply copy the font file Arial.ttf to the project directory and everything works.

Upvotes: 4

Hugo
Hugo

Reputation: 29334

According to the PIL documentation, only Windows font directory is searched:

On Windows, if the given file name does not exist, the loader also looks in Windows fonts directory.

http://effbot.org/imagingbook/imagefont.htm

So you need to write your own code to search for the full path on Linux.

However, Pillow, the PIL fork, currently has a PR to search a Linux directory. It's not exactly clear yet which directories to search for all Linux variants, but you can see the code here and perhaps contribute to the PR:

https://github.com/python-pillow/Pillow/pull/682

Upvotes: 17

Related Questions