InkyPhat - how to wrap text - help needed


#1

Hi there, I’m new to this, probably this is a beginner level thing, but I can’t do it alone. I love InkyPhat display, but I need some help in printing longer texts in it.

Of course,

import sys
from PIL import ImageFont
import inkyphat
font = ImageFont.truetype(inkyphat.fonts.FredokaOne, 16)
name = "text example"
w, h = font.getsize(name)
x = (inkyphat.WIDTH / 2) - (w / 2)
y = (inkyphat.HEIGHT / 2) - (h / 2)
inkyphat.text((x, y), name, inkyphat.BLACK, font)
inkyphat.show()

will print a perfectly centred single black line text on the InkyPhat display, but limited to this single line and the display width, longer texts will be truncated.

Starting from above, I need to know if there’s a possibility to print longer texts in several lines, somehow auto-adjusted (warped) to the display size, eventually dynamically centred (keeping all the possibilities from a single centred line to several centred lines when the text is large than a single line).

Thank you,
Alex


#2

Since Inky pHAT just uses PIL/Pillow you should be able to use the multiline_text method: http://pillow.readthedocs.io/en/3.3.x/reference/ImageDraw.html?highlight=multiline_text#PIL.ImageDraw.PIL.ImageDraw.Draw.multiline_text

However this method is not yet exposed for Inky pHAT (I’ll have to make a note to do that in the next release) so you will, if I’m not talking nonsense, need to do:

inkyphat._draw.multiline_text(args ...)

#3

Hi Phil,
Thank you for your time and quick answer. As far as I understand (my knowledge is minimal in this area) I have to wait for an updated Inky pHAT software release to be able to use multiline_text, is that right?

A code like this will get an attribute error: “ImageDraw instance has no attribute ‘multiline_text’”

from PIL import ImageFont
from PIL import ImageDraw
import inkyphat
font = ImageFont.truetype(inkyphat.fonts.FredokaOne, 16)
name = "text example too big to fit a single line on InkyPhat"
w, h = font.getsize(name)
x = (inkyphat.WIDTH / 2) - (w / 2)
y = (inkyphat.HEIGHT / 2) - (h / 2)
inkyphat._draw.multiline_text((x, y), name, inkyphat.BLACK, font)
inkyphat.show()

Of course, as I told you above, my knowledge is minimal here, any example of a functional script will really help me.
Thank you,
Alex


#4

Drat I’d totally failed to notice that the version of PIL/Pillow available via apt is woefully out of date and doesn’t have shiny new stuff like multiline_text :(

Technically inkyphat._draw.multiline_text should work, even without an Inky pHAT library update, because it just calls the method on the ImageDraw object directly (which will have whatever methods ImageDraw does in whatever version of Pillow it’s running).

Unfortunately, this version isn’t in the old Pillow available via Raspbian’s repos.

You might have some luck with an updated version, which can be installed by doing something like:

sudo apt remove python-inkyphat python-pil
sudo apt install libjpeg-dev
sudo pip install pillow --upgrade
sudo pip install inkyphat

Then if you import PIL and hit PIL.PILLOW_VERSION in a Python REPL you should see something like: 4.2.1

And if you call dir(inkyphat._draw) you should see: multiline_text:

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', 
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
'__weakref__', '_getink', '_multiline_check', '_multiline_split', 'arc', 'bitmap', 'chord', 'draw', 'ellipse', 'fill', 'font', 'fontmode', 
'getfont', 'im', 'ink', 'line', 'mode', 'multiline_text', 'multiline_textsize', 'palette', 'pieslice', 'point', 'polygon', 'rectangle', 
'shape', 'text', 'textsize']

#5

Hi Phil, It seems I can’t install:
sudo pip install pillow --upgrade

It just got me a bunch of errors. Probably something it isn’t compatible, I’ll try to figure out what’s happening.

"_imaging.c:74:20: fatal error: Python.h: No such file or directory
#include “Python.h"
compilation terminated.
error: command ‘arm-linux-gnueabihf-gcc’ failed with exit status 1”

Thank you,
Alex


#6

Make sure you have Python-dev installed before installing Pilow!
You can install both Python 2.7 and Python 3 like so:

sudo apt-get install python-dev python3-dev

Try with them installed and see how you go! :)


#7

^ That.

:D

Darn I forgot I almost always have python-dev installed :D


#8

Thank you all, I’m almost there! :)
I was able to install python-dev and pillow and everything seems to be in order, except the fact that the multiline_text I can’t get it working.

In the following code I’m assuming “/n” will start a new line in my text but it seems it doesn’t work. The text is printed on InkyPhat, but on a single line again, like there’s no multiline_text function. “/n” is actually printed as a character on the display. No errors is given.

from PIL import ImageFont
from PIL import ImageDraw
import inkyphat
font = ImageFont.truetype(inkyphat.fonts.FredokaOne, 16)
name = "text example too big/n to fit a single line on InkyPhat"
inkyphat._draw.multiline_text((5, 5), name, inkyphat.BLACK, font)
inkyphat.show()

Sorry for bother you with this, probably is just a simple thing I’m missing because of my lack of experience.
Thank you.


#9

You might be looking for “\n


#10

I assume you are using an up-to-date version of Debian Rapsbian right? Some operating systems use different new-line function placeholders.

^^Too late^^ :)


#11

Thank you all for your support, I finally done it :))
Here’s a code for everyone interested, maybe someone on the forum is in need for a similar solution:

import sys
from PIL import ImageFont
from PIL import ImageDraw
import inkyphat
import textwrap
font = ImageFont.truetype(inkyphat.fonts.FredokaOne, 16)
name = sys.argv[1]
txt = textwrap.fill(name, 27)
w, h = inkyphat._draw.multiline_textsize(txt, font)
x = (inkyphat.WIDTH / 2) - (w / 2)
y = (inkyphat.HEIGHT / 2) - (h / 2)
inkyphat._draw.multiline_text((x, y), txt, inkyphat.BLACK, font)
inkyphat.show()

Of course, this above if saved to a “text.py” file and executed from it’s own directory with
python text.py "Text to be printed on InkyPhat display"
will print a multiline text on InkyPhat. This will work for an approximately 120 characters long texts.