'PIL Issue, OSError: cannot open resource

I'm attempting to write a program that places text onto an image, I'm trying to get my head round PIL and have run into the error: OSError: cannot open resource. This is my first python program so apologies if the error is obvious.

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont


im = Image.open("example.jpg")
font_type = ImageFont.truetype("Arial.ttf", 18)
draw = ImageDraw.Draw(im)
draw.text(xy=(50, 50), text= "Text One", fill =(255,69,0), font = font_type)
im.show()

I get the error:

Traceback (most recent call last):
File "C:\Users\laurence.maskell\Desktop\attempt.py", line 7, in <module>
font_type = ImageFont.truetype("Arial.ttf", 18)
File "C:\Python34\lib\site-packages\PIL\ImageFont.py", line 259, in truetype
return FreeTypeFont(font, size, index, encoding, layout_engine)
File "C:\Python34\lib\site-packages\PIL\ImageFont.py", line 143, in __init__
self.font = core.getfont(font, size, index, encoding, 
layout_engine=layout_engine)
OSError: cannot open resource


Solution 1:[1]

I fixed the problem by using default font.

font = ImageFont.load_default()

If you just need to put some text (font style is not matter to you) then this might be a simple solution.

font = ImageFont.load_default()

draw = ImageDraw.Draw(pil_img)
draw.text(( 20, 32), "text_string", (255,0,0), font=font)

Solution 2:[2]

from PIL import Image, ImageDraw, ImageFont

im = Image.open("mak.png")
font_type = ImageFont.truetype("arial.ttf", 18)
draw = ImageDraw.Draw(im)
draw.text(xy=(120, 120), text= "download font you want to use", fill=(255,69,0), font=font_type)
im.show()

Its "arial.ttf" not "Arial.ttf"

Here is the link to download arial.ttf font.

Solution 3:[3]

I have also met this issue on Windows 10 Pro with PIL 5.3.0.

On my machine, the error is caused by non-ASCII font file names. If I change the the font name to only contain ASCII characters, I can open the font without any error.

Edit (2019-07-29): this is indeed a bug with ImageFont.truetype() method and it has been fixed in this pull request.

Solution 4:[4]

For Linux I used:

$ locate .ttf

/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-B.ttf
/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-BI.ttf
/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-C.ttf
/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-L.ttf
/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-LI.ttf
/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-M.ttf
/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-MI.ttf
/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-R.ttf
/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-RI.ttf
/usr/share/fonts/truetype/ubuntu-font-family/UbuntuMono-B.ttf
/usr/share/fonts/truetype/ubuntu-font-family/UbuntuMono-BI.ttf
/usr/share/fonts/truetype/ubuntu-font-family/UbuntuMono-R.ttf
/usr/share/fonts/truetype/ubuntu-font-family/UbuntuMono-RI.ttf

It actually returned A LOT MORE than that!

Then I took the python code posted here in Stack Overflow:

Plugged in the font name "Ubuntu-R.ttf" returned by locate:

color_palette = [BLUE, GREEN, RED]
image_w=200
image_h=200
region = Rect(0, 0, image_w, image_h)
imgx, imgy = region.max.x+1, region.max.y+1
image = Image.new("RGB", (imgx, imgy), WHITE)
draw = ImageDraw.Draw(image)
vert_gradient(draw, region, gradient_color, color_palette)
#image.text((40, 80),"No Artwork",(255,255,255))
#font = ImageFont.truetype(r'C:\Users\System-Pc\Desktop\arial.ttf', 40)
#font = ImageFont.load_default()
font = ImageFont.truetype("Ubuntu-R.ttf", int(float(image_w) / 6))
draw.text((int(image_w/12), int(image_h / 2.5)), "No Artwork", \
           fill=(0,0,0), font=font)
image.show()

And voila! I now have an image to display when there is no image to display in a music file I'm playing:

No Artwork.png

Solution 5:[5]

I was also facing the same issue. but later found out it was an issue with the slash. So, if anybody else missed this small thing, it's for you.

I had the font inside the font folder. When I tried to import the font using font/<font_name>.ttf, the code couldn't locate it. Replaced / with \ and it could locate the font.

Solution 6:[6]

PIL cannot find the specified font. Check that it exists, and that it is named with the exact same case. You can also try to copy it directly in the project folder.

Solution 7:[7]

I think you should move the font to fonts or any folder. I had the same issue on heroku. After i moved the font to fonts directory it works

Solution 8:[8]

When I ran into this issue in Linux, I solved by:

  1. Install the .ttf into Linux

  2. Run the code with the actual .tff in ~. For some reason, even with the font installed and the .py running inn another dir, it needed to have the .tff in the home dir.

Solution 9:[9]

This issue also crops up in PIL for android. While it is quite possible to copy a font file into the project directory as others have noted, if more than a few android fonts are wanted it may be tidier to add the android font directory to the ImageFont.py search path instead. I altered it like this between lines 870-871:

870     elif sys.platform in ("linux", "linux2"):
            if 'ANDROID_BOOTLOGO' in os.environ:
                # kludge added for android
                dirs += [
                    "/system/fonts"
                ]
            else:
871             lindirs = os.environ.get("XDG_DATA_DIRS", "")
872             if not lindirs:
...                 # According to the freedesktop spec, XDG_DATA_DIRS should
                    # default to /usr/share
                    lindirs = "/usr/share"
                dirs += [os.path.join(lindir, "fonts") for lindir in lindirs.split(":")]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Jarad
Solution 3
Solution 4 WinEunuuchs2Unix
Solution 5 syd
Solution 6 blackbox
Solution 7 Shohruh
Solution 8 gorillaz4Sale
Solution 9 J B