python-how to solve OSError: cannot open resource when using python?

1. Purpose

In this post, I would demo how to solve the below exception or error when using python:

Traceback (most recent call last):
  File "generate_png_transparent_demo.py", line 43, in <module>
    generate_png_transparent("./images/a.png","hello world")
  File "generate_png_transparent_demo.py", line 37, in generate_png_transparent
    d.text((10,25), the_text, fill=(255, 0, 0),font=get_font(the_text))
  File "generate_png_transparent_demo.py", line 21, in get_font
    font = ImageFont.truetype("arial.ttf", fontsize)
  File "/Users/bswen/.pyenv/versions/3.7.6/lib/python3.7/site-packages/PIL/ImageFont.py", line 852, in truetype
    return freetype(font)
  File "/Users/bswen/.pyenv/versions/3.7.6/lib/python3.7/site-packages/PIL/ImageFont.py", line 849, in freetype
    return FreeTypeFont(font, size, index, encoding, layout_engine)
  File "/Users/bswen/.pyenv/versions/3.7.6/lib/python3.7/site-packages/PIL/ImageFont.py", line 210, in __init__
    font, size, index, encoding, layout_engine=layout_engine
OSError: cannot open resource

2. The Environment

  • Python 3
  • MacOS

3. The code

3.1 The project directory structure

Our working directory name is myscript, this is the structure of it:

.
└── myscripts/
    ├── images/
    │   ├── readme.txt
    └── generate_png_transparent_demo.py

Explain as follows:

  • The images directory is a target directory that we would put our result image into it
  • The generate_png_transparent_demo.py is the file that do the magic

3.2 The code that cause the problem

def get_font():
    font = ImageFont.truetype("arial.ttf", fontsize)

According to the ImageFont.truetype’s documentation, the first parameter of the function is the font file name, just as follows:

  • font – A truetype font file. Under Windows, if the file is not found in this filename, the loader also looks in Windows fonts/ directory.

When we run the above code, we get this error:

...
    font = ImageFont.truetype("arial.ttf", fontsize)
  File "/Users/bswen/.pyenv/versions/3.7.6/lib/python3.7/site-packages/PIL/ImageFont.py", line 852, in truetype
    return freetype(font)
  File "/Users/bswen/.pyenv/versions/3.7.6/lib/python3.7/site-packages/PIL/ImageFont.py", line 849, in freetype
    return FreeTypeFont(font, size, index, encoding, layout_engine)
  File "/Users/bswen/.pyenv/versions/3.7.6/lib/python3.7/site-packages/PIL/ImageFont.py", line 210, in __init__
    font, size, index, encoding, layout_engine=layout_engine
OSError: cannot open resource

You can see the program is complaining that it can not find the font file on the system.

3.3 The solution

We should tell python where to load the font file , just as follows:

def get_font(txt, img_fraction=0.05):
    font = ImageFont.truetype("/Library/fonts/Arial.ttf", fontsize)

Re-run the program, no errors again.

3.4 Why?

On windows system, python PIL libraray would find the font file in system font directories, but on MacOS, it seems that the library can not find the font file by itself.

Where is the font file on Mac?According to Mark Setchell and Nathaniel, the files are located at :

/System/Library/Fonts
/Library/Fonts

you can check in both at the same time from Terminal:

$ find {/System,}/Library/Fonts -name \*ttf

5. Summary

In this post, we demonstrated how to use solve the system font file problem when using PIL in python, you can see that the PIL is not very compatible with MacOS, there is a trick on this job. Thanks for your reading. Regards.