【问题标题】:Loading font from URL to Pillow将字体从 URL 加载到 Pillow
【发布时间】:2021-02-18 20:14:58
【问题描述】:

有没有办法直接从 url 加载带有 Pillow 库的字体,最好是加载到 Google Colab 中?我尝试了类似的东西

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

但我收到 OSError: cannot open resource 的错误。我也尝试过使用谷歌字体,但无济于事。

【问题讨论】:

  • 通过提供一个可用的 URL 让人们更容易为您提供帮助怎么样?
  • 我的错,马克;更新了 Q。

标签: python python-3.x python-imaging-library google-colaboratory


【解决方案1】:

你可以
(1) 通过 HTTP GET 请求获取字体,使用urllib.request.urlopen()
(2) 使用@functools.lrucache@memoization.cache 记住结果,这样每次运行函数时都不会获取字体,
(3) 将内容作为类文件对象传递给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)

还有python-memoization (pip install memoization) 用于替代记忆方式。用法将是

from memoization import cache 

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

记忆速度

没有记忆:

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)

有记忆:

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

【讨论】:

  • 这很好,很彻底,谢谢你。 @Mark 的回复仍然是一个快速简短的解决方案,所以我会接受他的回答,希望你不介意。
  • 谢谢 :) 是的,如果我看到已经有一个答案,我实际上不会写答案。您可以为此添加一些重试(例如使用坚韧)以及 zip 文件处理。只需添加一个参数即可完成 Zip 文件处理:webfont(font_url, filetype='zip'),然后在需要时添加 unzip。
【解决方案2】:

试试这样:

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)

【讨论】:

  • 这很快。值得一提的是,BytesIO 存在于 io 库中,我们也需要导入该库。如果字体在 zip 文件中怎么办,你有一个快速提示吗?还是再发一个问题比较好?
  • 问题是免费的(和答案),所以请继续问另一个...小心提供一个有代表性的 URL ?
  • 这里又加了一个问题,也许你可以看看? stackoverflow.com/questions/64730209/…
猜你喜欢
  • 2016-11-05
  • 2016-08-14
  • 1970-01-01
  • 2013-09-18
  • 2017-02-21
  • 1970-01-01
  • 2018-03-03
  • 2015-07-02
  • 2017-07-13
相关资源
最近更新 更多