Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading Images from file result in nothing being displayed #46

Open
powahftw opened this issue Feb 10, 2020 · 3 comments
Open

Loading Images from file result in nothing being displayed #46

powahftw opened this issue Feb 10, 2020 · 3 comments
Labels

Comments

@powahftw
Copy link

Hello! I'm encountering an issue when trying to display images on my Black/White Inky Phat.

I generate the image using PIL. I save it locally it looks good (see attached pic)

The way I save it is:

img.convert('P').save("test.png") (If I don't convert it I get ValueError: cannot reshape array of size 66144 into shape (104,212)

When I load it with:
Image.open("test.png").convert('P')

The screen flashed and then stays white.
If I do the last step, but with pointing the path to the Inky Example image it works correctly.
How to I save correctly the image so that it works when I load it back?

@Gadgetoid
Copy link
Member

The palette order and size matters, and I think the colour order is pretty arbitrary in an image you convert with PIL.

A "P" image could contain anywhere up to 256 colours, but Inky only cares about index 0 (white), 1 (black) and 2 (red or yellow).

When you convert your image- which contains anti-aliased text- you're probably inadvetently creating a palette of maybe 16 colours, which may not necessarily align with how Inky expects them.

One method of avoiding this is to create your image as "P" in the first place, and use explicit palette indexes in lieu of colours- ie instead of using a colour triplet in PIL drawing functions (0, 0, 0) just specify a single number. You don't really need an attached palette, because Inky wont use it.

Another method, if you're dead set on using an RGB source image, is to use PIL's quantize method. This may not give results you're happy with, as it'll smash all your text anti-aliasing to the nearest available colour (black or white). But bear in mind Inky can't display greyscale colour values, so the output will be representative of what you'll see on the display.

Here's a quick example of that process in action for a White/Black/Red display. This will also work for White/Black:

from PIL import Image, ImageDraw, ImageFont
from fonts.ttf import Roboto

image = Image.new('RGB', (212, 104))

font = ImageFont.truetype(Roboto)

draw = ImageDraw.Draw(image)

draw.text((0, 0), "Hello World", font=font, fill=(200, 200, 200))
draw.text((0, 20), "Oh boy, this looks bad!", font=font, fill=(200, 0, 0))
image.save("before.png")

palette = Image.new('P', (1, 1))
palette.putpalette(
[
    255, 255, 255,   # 0 = White
    0, 0, 0,         # 1 = Black
    255, 0, 0,       # 2 = Red (255, 255, 0 for yellow)
] + [0, 0, 0] * 253  # Zero fill the rest of the 256 colour palette
)

# Quantize our image using Inky's 3-colour palette
image = image.quantize(colors=3, palette=palette)

# Save the image
image.save("after.png")

Before quantization

before

After quantization

after

I should probably put this example and guide in the docs somewhere, but for now I hope this helps.

@powahftw
Copy link
Author

Hello Philip, many thanks for the detailed help! That solved my issue.

The reason for using 'RGB' in the first place was that 'P' was also not behaving as expected for me.
In the end I think it was related to using a (0,0,0) tuple instead of a 0 value, which I now fixed.

Whish you a great week!

p.s. Also handling everything in 'RGB', with only the last step going to 'P', was nice as it allows to write modular code that can be used for every kind of display, instead of only Inky.

@powahftw
Copy link
Author

Hey Philip, small follow up with a quick question. Hopefully it can also be useful to others folks who search for such a similar issue.
It all works nicely with the 'P' mode, but for logging purposes I'd like to save the displayed screenshot in a log folder (so I can check them out later).

Saving the 'P' mode images is giving me a black screen on my image viewer software (as they probably get picked up as 0/1 out of 255).

What would you suggest as a way to overcome this?
Is using https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.convert
to convert it to RGB, with a conversion matrix that map 0 -> (255, 255, 255) and 1 -> (0, 0, 0) the best way to go about this?

@powahftw powahftw reopened this Feb 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants