rm-hull / luma.examples

Companion repo for running examples against the luma.oled, luma.lcd, luma.led_matrix and luma.emulator display drivers.
MIT License
380 stars 147 forks source link

luma.core.render.canvas, text() (PIL ImageDraw) requires UTF-8 default font? #65

Closed gnbl closed 6 years ago

gnbl commented 7 years ago

Hi again, I encountered another minor problem when playing with the examples. I just noticed that I might be running 2017-08-16-raspbian-stretch-lite which might explain some missing dependencies .. or missing fonts...

The problem

pi@raspberry:~/luma.examples/examples $ python3 bounce.py -d ssd1322 --width 256                                                                                     --height 64 -i spi
Display: ssd1322
Interface: spi
Dimensions: 256 x 64
----------------------------------------
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/PIL/ImageDraw.py", line 220, in t                                                                                    ext
    mask, offset = font.getmask2(text, self.fontmode, *args, **kwargs)
AttributeError: 'ImageFont' object has no attribute 'getmask2'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "bounce.py", line 81, in <module>
    main()
  File "bounce.py", line 72, in main
    c.text((2, 0), fps, fill="white")
  File "/usr/local/lib/python3.5/dist-packages/PIL/ImageDraw.py", line 224, in t                                                                                    ext
    mask = font.getmask(text, self.fontmode, *args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/PIL/ImageFont.py", line 114, in g                                                                                    etmask
    return self.font.getmask(text, mode)
SystemError: <built-in method getmask of ImagingFont object at 0x23fce80> return                                                                                    ed NULL without setting an error

One of the first search hits suggests that a Unicode-capable font is required (but I did not research further, so it may be another cause), and here's my path to resolving it at the examples source (in the logical order):

Find out what fonts can be used

pi@raspberry:~/luma.examples/examples $ sudo apt-get install fontconfig
...
pi@raspberry:~/luma.examples/examples $ fc-list
/usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf: DejaVu Serif:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf: DejaVu Sans Mono:style=Book
/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf: DejaVu Sans:style=Book
/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf: DejaVu Sans:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf: DejaVu Sans Mono:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf: DejaVu Serif:style=Book

Use one of these in the example:

pi@raspberry:~/luma.examples/examples $ git diff bounce.py
diff --git a/examples/bounce.py b/examples/bounce.py
index 7e10916..d9f46cc 100755
--- a/examples/bounce.py
+++ b/examples/bounce.py
@@ -59,6 +59,9 @@ def main(num_iterations=sys.maxsize):

     regulator = framerate_regulator(fps=0)

+    from PIL import ImageFont
+    font = ImageFont.truetype("DejaVuSans.ttf")
+
     while num_iterations > 0:
         with regulator:
             num_iterations -= 1
@@ -69,7 +72,7 @@ def main(num_iterations=sys.maxsize):
                 for b in balls:
                     b.update_pos()
                     b.draw(c)
-                c.text((2, 0), fps, fill="white")
+                c.text((2, 0), fps, fill="white", font=font)

             if frame_count % 20 == 0:
                 fps = "FPS: {0:0.3f}".format(regulator.effective_FPS())
pi@raspberry:~/luma.examples/examples $ python3 bounce.py -d ssd1322 --width 256 --height 64 -i spi
Display: ssd1322
Interface: spi
Dimensions: 256 x 64
----------------------------------------
^C

Quick search shows font setting only in:

On the other hand, greyscale.py also renders text but does not show this issue.

Sorry I can't pinpoint this further.

pi@raspberry:~/luma.examples $ git show
commit 06aade8489bdf95c693fdf0323c541bfbbb04385
Author: Thijs Triemstra <info@***.nl>
Date:   Fri Oct 27 10:09:21 2017 +0200

    flake8 config update (#64)

pi@raspberry:~/luma.examples $ pip3 show luma.oled
Name: luma.oled
Version: 2.2.12
Summary: A small library to drive an OLED device with either SSD1306, SSD1322, SSD1325, SSD1331 or SH1106 chipset
Home-page: https://github.com/rm-hull/luma.oled
Author: Richard Hull
Author-email: richard.hull@***.org
License: MIT
Location: /usr/local/lib/python3.5/dist-packages
Requires: luma.core
pi@raspberry:~/luma.examples $ pip3 show luma.core
Name: luma.core
Version: 1.0.3
Summary: A component library to support SBC display drivers
Home-page: https://github.com/rm-hull/luma.core
Author: Richard Hull
Author-email: richard.hull@***.org
License: MIT
Location: /usr/local/lib/python3.5/dist-packages
Requires: spidev, RPI.GPIO, pillow, smbus2
rm-hull commented 7 years ago

[I have a sneaking suspicion it is down to a pillow version mismatch, as I have seen something similar before]

rm-hull commented 7 years ago

fyi, you can just use $ python3 bounce.py -f conf/ssd1322.conf and it will load in the config settings from the file. You can of course specify extra params after the -f flag, and they will overwrite the loaded in ones.

gnbl commented 7 years ago
pi@raspberry:~/luma.examples/examples $ pip3 show pillow
Name: Pillow
Version: 4.3.0
Summary: Python Imaging Library (Fork)
Home-page: https://python-pillow.org
Author: Alex Clark (Fork Author)
Author-email: aclark@***.net
License: Standard PIL License
Location: /usr/local/lib/python3.5/dist-packages
Requires: olefile
pi@raspberry:~/luma.examples/examples $ echo $LANG
en_GB.UTF-8

Thanks for the hint. Where did you get the SSD1322 init values? They seem to differ a bit from the few manufacturer's examples.

rm-hull commented 7 years ago

Ok, so you have the latest pillow, so we can scratch that idea. If you don't explicitly specify a font, it should default to pillow's default bitmapped font. Like you say, maybe this is missing on your strech-lite distro. I will get hold of that and have a look.

The init sequence would've been initially based off of what looked relevant in the datasheet (see https://luma-oled.readthedocs.io/en/latest/_downloads/SSD1322.pdf), then -erm- some not-insignificant tinkering on my part. Broadly, they should have the same commands, but some of the data fields may well have diverged.

gnbl commented 7 years ago

The default font is hardcoded:

  1. https://github.com/python-pillow/Pillow/blob/master/PIL/ImageDraw.py#L215
  2. https://github.com/python-pillow/Pillow/blob/master/PIL/ImageDraw.py#L89
  3. https://github.com/python-pillow/Pillow/blob/master/PIL/ImageFont.py#L326

and does not contain information about itself:

Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170124] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from PIL import Image, ImageDraw, ImageFont
>>> im = Image.new("RGB", (100,100))
>>> draw = ImageDraw.Draw(im)
>>> f=draw.getfont()
>>> f.info
[]
>>> f.file
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'ImageFont' object has no attribute 'file'

I haven't looked into where/why getmask fails.

If anyone wanted to tweak display parameters for these panels: Newhaven, Eastrising and Densitron provide example code and/or init sequences in their display/module datasheets that are quite similar (either copied or from the same source?).

thijstriemstra commented 7 years ago

Can you try with an older pillow version?

gnbl commented 7 years ago

If you could give me pointers on how to selectively use an older version (which?), I'll give it a try.

thijstriemstra commented 7 years ago
pip install Pillow==4.2.0
gnbl commented 7 years ago

This would overwrite the current version. Sorry, changed my mind.

thijstriemstra commented 6 years ago

@gnbl did you sort it out? can this be closed?

gnbl commented 6 years ago

Whatever

thijstriemstra commented 6 years ago

I don't like your attitude @gnbl.