0

I am having problems loading fonts in memory, directly from GCS, without creating temporary files.

The goal is to load it into:

from PIL import Image, ImageFont, ImageDraw
BUCKET_NAME = 'bucket_name'
gs_path = 'path_in_bucket/object.otf'
font_file = load_font_from_gcs(gs_path)
font = ImageFont.truetype(font_file, 18)

I tried using the following 2 functions to download:

from google.cloud import storage

storage_client = storage.Client()

def load_font_from_gcs(gs_path):
    font_file = download_blob_as_string(gs_path)
    return font_file

def download_blob_as_string(source_blob_name, bucket_name=BUCKET_NAME):
    """Downloads a blob from the bucket as string."""

    storage_client = storage.Client()

    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(source_blob_name)
    return blob.download_as_string()

However, I keep running into encoding/decoding errors or type errors e.g.

File "/anaconda3/envs/ml36/lib/python3.6/site-packages/PIL/ImageFont.py", line 161, in init font, size, index, encoding, layout_engine=layout_engine TypeError: argument 1 must be encoded string without null bytes, not bytes

GRS
  • 2,807
  • 4
  • 34
  • 72
  • The `download_as_string()` function, as its name does not imply, returns bytes (see https://googleapis.dev/python/storage/latest/blobs.html#google.cloud.storage.blob.Blob.download_as_string). Maybe your issue is related? – norbjd Feb 17 '20 at 17:00
  • I know that it returns bytes, the thing is that `PIL/ImageFont.py` should process bytes. I think there is a bug in logic since if platform != win32, we do not use the bytes anywhere – GRS Feb 17 '20 at 17:26
  • https://github.com/python-pillow/Pillow/blob/1cecf08d16509c20473766b4cdb7a65169844819/src/PIL/ImageFont.py#L188 This line should be ```self.font = core.getfont( "", size, index, encoding, self.font_bytes, layout_engine )``` – GRS Feb 17 '20 at 17:30

1 Answers1

1

Wrapping it in a BytesIO works on my Mac:

from io import BytesIO
...
...
font_file = load_font_from_gcs(gs_path)
font = ImageFont.truetype(BytesIO(font_file), 18)
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432