delimiter
delimiter

Reputation: 795

Loading font from URL to Pillow

Is there a way to load a font with Pillow library directly from url, preferably into Google Colab? I tried something like

from PIL import Image, ImageDraw, ImageFont ImageFont.truetype("https://github.com/googlefonts/roboto/blob/master/src/hinted/Roboto-Regular.ttf?raw=true", 15)

Yet I get an error of OSError: cannot open resource. I tried with Google Fonts too, but to no avail. enter image description here

Upvotes: 1

Views: 3225

Answers (2)

Mark Setchell
Mark Setchell

Reputation: 207520

Try it like this:

import requests
from io import BytesIO

req = requests.get("https://github.com/googlefonts/roboto/blob/master/src/hinted/Roboto-Regular.ttf?raw=true")

font = ImageFont.truetype(BytesIO(req.content), 72)

Upvotes: 1

Niko Fohr
Niko Fohr

Reputation: 33840

You can
(1) Fetch the font with HTTP GET request, using urllib.request.urlopen()
(2) memoize the result with @functools.lrucache or @memoization.cache so the font is not fetched every time you run the function and
(3) Pass the contents as a file-like object with io.BytesIO

from PIL import ImageFont
import urllib.request
import functools
import io


@functools.lru_cache
def get_font_from_url(font_url):
    return urllib.request.urlopen(font_url).read()


def webfont(font_url):
    return io.BytesIO(get_font_from_url(font_url))


if __name__ == "__main__":
    font_url = "https://github.com/googlefonts/roboto/blob/master/src/hinted/Roboto-Regular.ttf?raw=true"
    with webfont(font_url) as f:
        imgfnt = ImageFont.truetype(f, 15)

There is also python-memoization (pip install memoization) for alternative way of memoizing. Usage would be

from memoization import cache 

@cache
def get_font_from_url(font_url):
    return urllib.request.urlopen(font_url).read()

memoization speed

Without memoization:

In [1]: timeit get_font_from_url(font_url)
The slowest run took 4.95 times longer than the fastest. This could mean that an intermediate result is being cached.
1.32 s ± 1.11 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

With memoization:

In [1]: timeit get_font_from_url(font_url)
The slowest run took 11.00 times longer than the fastest. This could mean that an intermediate result is being cached.
271 ns ± 341 ns per loop (mean ± std. dev. of 7 runs, 1 loop each)
```t

Upvotes: 4

Related Questions