Updated for new driver files
This commit is contained in:
parent
2e9e2b80bb
commit
002ed089f3
@ -2,82 +2,166 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
Experimental image module for Inky-Calendar software
|
Experimental image module for Inky-Calendar software
|
||||||
Displays an image on the E-Paper. Currently only supports black and white
|
Displays an image on the E-Paper. Work in progress!
|
||||||
Copyright by aceisace
|
Copyright by aceisace
|
||||||
"""
|
"""
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
from PIL import Image
|
|
||||||
from configuration import *
|
from configuration import *
|
||||||
import os
|
from os import path
|
||||||
|
from PIL import ImageOps
|
||||||
|
import requests
|
||||||
|
import numpy
|
||||||
|
|
||||||
import inkycal_drivers as drivers
|
"""----------------------------------------------------------------"""
|
||||||
|
#path = 'https://github.com/aceisace/Inky-Calendar/raw/master/Gallery/Inky-Calendar-logo.png'
|
||||||
|
path ='/home/pi/Inky-Calendar/images/canvas.png'
|
||||||
|
mode = 'auto' # 'horizontal' # 'vertical' # 'auto'
|
||||||
|
upside_down = True # Flip image by 180 deg (upside-down)
|
||||||
|
alignment = 'center' # top_center, top_left, center_left, bottom_right etc.
|
||||||
|
colours = 'bwr' # bwr # bwy # bw
|
||||||
|
render = True # show image on E-Paper?
|
||||||
|
"""----------------------------------------------------------------"""
|
||||||
|
|
||||||
display = drivers.EPD()
|
"""Try to open the image if it exists and is an image file"""
|
||||||
|
try:
|
||||||
|
if 'http' in path:
|
||||||
|
im = Image.open(requests.get(path, stream=True).raw)
|
||||||
|
else:
|
||||||
|
im = Image.open(path)
|
||||||
|
except FileNotFoundError:
|
||||||
|
print('Your file could not be found. Please check the path to your file.')
|
||||||
|
raise
|
||||||
|
except OSError:
|
||||||
|
print('Please check if the path points to an image file.')
|
||||||
|
raise
|
||||||
|
|
||||||
# Where is the image?
|
"""Turn image upside-down if specified"""
|
||||||
path = '/home/pi//Desktop/test.JPG'
|
if upside_down == True:
|
||||||
|
im.rotate(180, expand = True)
|
||||||
|
|
||||||
class inkycal_image:
|
if mode == 'horizontal':
|
||||||
|
display_width, display_height == display_height, display_width
|
||||||
|
|
||||||
def __init__(self, path):
|
if mode == 'vertical':
|
||||||
self.image = Image.open(path)
|
pass
|
||||||
self.im_width = self.image.width
|
|
||||||
self.im_height = self.image.height
|
|
||||||
|
|
||||||
def check_mode(self):
|
if mode == 'auto':
|
||||||
if self.image.mode != 'RGB' or 'L' or '1':
|
if (im.width > im.height) and (display_width < display_height):
|
||||||
print('Image mode not supported, converting')
|
print('display vertical, image horizontal -> flipping image')
|
||||||
self.image = self.image.convert('RGB')
|
im = im.rotate(90, expand=True)
|
||||||
|
if (im.width < im.height) and (display_width > display_height):
|
||||||
|
print('display horizontal, image vertical -> flipping image')
|
||||||
|
im = im.rotate(90, expand=True)
|
||||||
|
|
||||||
def preview(self):
|
def fit_width(image, width):
|
||||||
self.image.save(path+'temp.png')
|
"""Resize an image to desired width"""
|
||||||
os.system("gpicview "+path+'temp.png')
|
print('resizing width from', image.width, 'to', end = ' ')
|
||||||
os.system('rm '+path+'temp.png')
|
wpercent = (display_width/float(image.width))
|
||||||
|
hsize = int((float(image.height)*float(wpercent)))
|
||||||
|
img = image.resize((width, hsize), Image.ANTIALIAS)
|
||||||
|
print(img.width)
|
||||||
|
return img
|
||||||
|
|
||||||
|
def fit_height(image, height):
|
||||||
|
"""Resize an image to desired height"""
|
||||||
|
print('resizing height from', image.height, 'to', end = ' ')
|
||||||
|
hpercent = (height / float(image.height))
|
||||||
|
wsize = int(float(image.width) * float(hpercent))
|
||||||
|
img = image.resize((wsize, height), Image.ANTIALIAS)
|
||||||
|
print(img.height)
|
||||||
|
return img
|
||||||
|
|
||||||
|
if im.width > display_width:
|
||||||
|
im = fit_width(im, display_width)
|
||||||
|
if im.height > display_height:
|
||||||
|
im = fit_height(im, display_height)
|
||||||
|
|
||||||
|
if alignment == 'center':
|
||||||
|
x,y = int((display_width-im.width)/2), int((display_height-im.height)/2)
|
||||||
|
elif alignment == 'center_right':
|
||||||
|
x, y = display_width-im.width, int((display_height-im.height)/2)
|
||||||
|
elif alignment == 'center_left':
|
||||||
|
x, y = 0, int((display_height-im.height)/2)
|
||||||
|
|
||||||
|
elif alignment == 'top_center':
|
||||||
|
x, y = int((display_width-im.width)/2), 0
|
||||||
|
elif alignment == 'top_right':
|
||||||
|
x, y = display_width-im.width, 0
|
||||||
|
elif alignment == 'top_left':
|
||||||
|
x, y = 0, 0
|
||||||
|
|
||||||
|
elif alignment == 'bottom_center':
|
||||||
|
x, y = int((display_width-im.width)/2), display_height-im.height
|
||||||
|
elif alignment == 'bottom_right':
|
||||||
|
x, y = display_width-im.width, display_height-im.height
|
||||||
|
elif alignment == 'bottom_left':
|
||||||
|
x, y = display_width-im.width, display_height-im.height
|
||||||
|
|
||||||
|
if len(im.getbands()) == 4:
|
||||||
|
print('removing transparency')
|
||||||
|
bg = Image.new('RGBA', (im.width, im.height), 'white')
|
||||||
|
im = Image.alpha_composite(bg, im)
|
||||||
|
|
||||||
|
image.paste(im, (x,y))
|
||||||
|
im = image
|
||||||
|
|
||||||
|
if colours == 'bw':
|
||||||
|
"""For black-white images, use monochrome dithering"""
|
||||||
|
black = im.convert('1', dither=True)
|
||||||
|
elif colours == 'bwr':
|
||||||
|
"""For black-white-red images, create corresponding palette"""
|
||||||
|
pal = [255,255,255, 0,0,0, 255,0,0, 255,255,255]
|
||||||
|
elif colours == 'bwy':
|
||||||
|
"""For black-white-yellow images, create corresponding palette"""
|
||||||
|
pal = [255,255,255, 0,0,0, 255,255,0, 255,255,255]
|
||||||
|
|
||||||
|
|
||||||
def check_size(self, alignment = 'middle', padding_colour='white'):
|
"""Map each pixel of the opened image to the Palette"""
|
||||||
if display_height < self.im_height or display_width < self.im_width:
|
if colours != 'bw':
|
||||||
print('Image too large for the display, cropping image')
|
palette_im = Image.new('P', (3,1))
|
||||||
if alignment == 'middle' or None:
|
palette_im.putpalette(pal * 64)
|
||||||
x1 = int((self.im_width - display_width) / 2)
|
quantized_im = im.quantize(palette=palette_im)
|
||||||
y1 = int((self.im_height - display_height) / 2)
|
quantized_im.convert('RGB')
|
||||||
x2,y2 = x1+display_width, y1+display_height
|
|
||||||
self.image = self.image.crop((x1,y1,x2,y2))
|
|
||||||
|
|
||||||
if alignment != 'middle' or None:
|
"""Create buffer for coloured pixels"""
|
||||||
print('Sorry, this feature has not been implemented yet')
|
buffer1 = numpy.array(quantized_im.convert('RGB'))
|
||||||
raise NotImplementedError
|
r1,g1,b1 = buffer1[:, :, 0], buffer1[:, :, 1], buffer1[:, :, 2]
|
||||||
|
|
||||||
elif display_height > self.im_height and display_width > self.im_width:
|
"""Create buffer for black pixels"""
|
||||||
print('Image smaller than display, shifting image to center')
|
buffer2 = numpy.array(quantized_im.convert('RGB'))
|
||||||
x = int( (display_width - self.im_width) /2)
|
r2,g2,b2 = buffer2[:, :, 0], buffer2[:, :, 1], buffer2[:, :, 2]
|
||||||
y = int( (display_height - self.im_height) /2)
|
|
||||||
canvas = Image.new('RGB', (display_width, display_height), color=padding_colour)
|
|
||||||
canvas.paste(self.image, (x,y))
|
|
||||||
self.image = canvas
|
|
||||||
|
|
||||||
else:
|
if colours == 'bwr':
|
||||||
print('Image file exact. no further action required')
|
"""Create image for only red pixels"""
|
||||||
|
buffer2[numpy.logical_and(r2 == 0, b2 == 0)] = [255,255,255] # black->white
|
||||||
|
buffer2[numpy.logical_and(r2 == 255, b2 == 0)] = [0,0,0] #red->black
|
||||||
|
colour = Image.fromarray(buffer2)
|
||||||
|
"""Create image for only black pixels"""
|
||||||
|
buffer1[numpy.logical_and(r1 == 255, b1 == 0)] = [255,255,255]
|
||||||
|
black = Image.fromarray(buffer1)
|
||||||
|
|
||||||
def auto_flip(self):
|
if colours == 'bwy':
|
||||||
if self.im_height < self.im_width:
|
"""Create image for only yellow pixels"""
|
||||||
print('rotating image')
|
buffer2[numpy.logical_and(r2 == 0, b2 == 0)] = [255,255,255] # black->white
|
||||||
self.image = self.image.rotate(270, expand=True)
|
buffer2[numpy.logical_and(g2 == 255, b2 == 0)] = [0,0,0] #yellow -> black
|
||||||
self.im_width = self.image.width
|
colour = Image.fromarray(buffer2)
|
||||||
self.im_height = self.image.height
|
"""Create image for only black pixels"""
|
||||||
|
buffer1[numpy.logical_and(g1 == 255, b1 == 0)] = [255,255,255]
|
||||||
|
black = Image.fromarray(buffer1)
|
||||||
|
|
||||||
|
if render == True:
|
||||||
|
epaper = driver.EPD()
|
||||||
|
print('Initialising E-Paper...', end = '')
|
||||||
|
epaper.init()
|
||||||
|
print('Done')
|
||||||
|
|
||||||
def to_mono(self):
|
print('Sending image data and refreshing display...', end='')
|
||||||
self.image = self.image.convert('1', dither=True)
|
if three_colour_support == True:
|
||||||
|
epaper.display(epaper.getbuffer(black), epaper.getbuffer(colour))
|
||||||
def prepare_image(self, alignment='middle'):
|
else:
|
||||||
self.check_mode()
|
epaper.display(epaper.getbuffer(black))
|
||||||
self.auto_flip()
|
print('Done')
|
||||||
self.check_size(alignment = alignment)
|
|
||||||
self.to_mono()
|
|
||||||
|
|
||||||
return self.image
|
|
||||||
|
|
||||||
#single line command:
|
|
||||||
display.show_image(inkycal_image(path).prepare_image(), reduce_colours=False)
|
|
||||||
|
|
||||||
|
print('Sending E-Paper to deep sleep...', end = '')
|
||||||
|
epaper.sleep()
|
||||||
|
print('Done')
|
||||||
|
Loading…
Reference in New Issue
Block a user