Forums

PIL imagefont issue in django

I'm trying to dynamically generate an image in django which includes text. I'm using Pillow in python 3.4. When I try to call ImageFont.truetype I get an OSError exception with the text 'cannot open resource'. The python code is a line like

font = ImageFont.truetype(http://brucelet.pythonanywhere.com/static/arial.ttf,144)

The equivalent code works fine when I run it from a shell outside the context of django, so I'm not really sure what's going on. Am I using the wrong url to point to the static folder (although in that case I would expect a FileNotFoundError)? Is there something when running in the context of django that doesn't like how PIL loads fonts?

That's odd, if it works in the console then it should work from a web app (so long as you're not using a virtualenv or something complicated like that, and it doesn't look like you are).

How are you running it from the console? Could you post more of the OSError's stacktrace?

from console, I'm just passing a script to python3.4 which contains similar code. The script I run locally is slightly different in that I load the ttf file from the current directory instead of the web app's static. I do get a similar error if I modify the console script to deliberately load a nonexistant file, which would seem to suggest that I'm just using the wrong url to access /static. However, If I toss that url at a browser I get served the ttf file to download so it would appear to be correct. Perhaps ImageFont.truetype just can't deal with being handed a web url?

Full stack trace follows:

Environment:


Request Method: GET
Request URL: http://brucelet.pythonanywhere.com/calendar/month/2014/6/

Django Version: 1.6.5
Python Version: 3.4.1
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'timezone_field',
 'CalendarApp',
 'BrucePhrase',
 'polls')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware')


Traceback:
File "/usr/local/lib/python3.4/dist-packages/django/core/handlers/base.py" in get_response
  112.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/Brucelet/SunMoonCalendar/CalendarApp/views.py" in dynamic_calendar
  69.     font = ImageFont.truetype(fontpath,144)
File "/home/Brucelet/.local/lib/python3.4/site-packages/PIL/ImageFont.py" in truetype
  228.         return FreeTypeFont(font, size, index, encoding)
File "/home/Brucelet/.local/lib/python3.4/site-packages/PIL/ImageFont.py" in __init__
  131.             self.font = core.getfont(font, size, index, encoding)

Exception Type: OSError at /calendar/month/2014/6/
Exception Value: cannot open resource

What's the URL you're passing it? (Use the "Send feedback" link above right if you don't want it to be public here on the forums.)

It's in my initial post: http://brucelet.pythonanywhere.com/static/arial.ttf

Ah, right. Actually, looking at the docs for PIL it looks like your suspicion is right -- the truetype method takes a filename, and doesn't accept URLs. If you pass it a filename then everything should work fine.

Yeah I figured out late last night that I could just use a local path. For some reason I was assuming that in a web app I couldn't access the local filesystem the same way.

That's not a crazy assumption, with some other hosting platforms the file storage works differently in web apps. But on PythonAnywhere it should be fine.