47

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
Laurence Maskell
  • 611
  • 1
  • 5
  • 6

14 Answers14

30

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)
Uzzal Podder
  • 2,925
  • 23
  • 26
20
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.

Jarad
  • 17,409
  • 19
  • 95
  • 154
Kartik
  • 301
  • 2
  • 3
  • 4
    After downloading arial.tff I was able to get my program to work after moving the .tff file into the same directory as the script (I actually just use wget $URL in the directory) and then I used ./arial.tff (this uses the one in your directory) instead of arial.tff (this one searches your system for the file) – Seabass77 Feb 26 '19 at 15:26
9

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.

jdhao
  • 24,001
  • 18
  • 134
  • 273
5

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

WinEunuuchs2Unix
  • 1,801
  • 1
  • 17
  • 34
2

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.

syd
  • 195
  • 1
  • 2
  • 10
1

As I have understood, a problem with location of the file: "Arial.ttf"

As I have understood the Arial.ttf file is with the program, but start is made from other place.

In this case it is necessary to add the Arial.ttf file to a full path:

# __file__ contain full path to the py scrypt
# for python 3.9 and later 

import os
path = os.path.dirname(__file__) + '/'

im = Image.open("example.jpg")
font_type = ImageFont.truetype(path + "Arial.ttf", 18)

For older py version see more at: How do I get the full path of the current file's directory?

Timur U
  • 415
  • 2
  • 14
1

If you are on Windows, by the following method my problem was resolved:

  • go to the Font folder in C:\Windows\Fonts
  • Right-click on the font that you want to use and click on "Properties"
  • go to the Security tab and copy the address of "Object name:"
  • then place the above path (*****) in the following code:

ImageFont.truetype("*****", int(float(image_w) / 6))

0

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.

blackbox
  • 671
  • 6
  • 18
0

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

Shohruh
  • 1
  • 2
0

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.

0

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(":")]
J B
  • 348
  • 1
  • 6
0

It's just that the name of the .ttf file does'nt match with the filename you pass to ImageFont.truetype().

Make sure that the case and spelling are correct. There is no other external factor that could affect merely loading a font from a ttf file.

Caffeine
  • 11
  • 1
0

I solved it simply by doing the following steps:

  1. Created a hidden folder named fonts (.fonts) in the home directory.
  2. Downloaded my desired font from the web. Note: You can download any font you want by typing "font_name.tiff download" on Google.
  3. Copy and paste the downloaded .ttf file into the .fonts folder.
  4. Copy and paste the new path of your .ttf file in the code as shown below.
im_show = draw_ocr(image, boxes, txts, scores, font_path='/.fonts/simfang.ttf')

That's how it worked for me.

You can follow this link as a visual aid. https://www.youtube.com/watch?v=Q5GO_glHXyQ&t=35s

bfris
  • 5,272
  • 1
  • 20
  • 37
0

I used the following solution for PaddleOCR draw_structure_result:

Download .tiff file(you can use https://www.wfonts.com/font/tiff-heavy) and store them in a folder and give the path of that folder:

im_show = draw_structure_result(img, result, font_path='/content/TIFFH.ttf')