def test_init_what_setup(spidev, smbus2, GPIO): """Test initialisation and setup of InkyWHAT. Verify our expectations for GPIO setup in order to catch regressions. """ from inky import InkyWHAT # TODO: _busy_wait should timeout after N seconds GPIO.input.return_value = GPIO.LOW inky = InkyWHAT('red') inky.setup() # Check GPIO setup GPIO.setwarnings.assert_called_with(False) GPIO.setmode.assert_called_with(GPIO.BCM) GPIO.setup.assert_has_calls([ mock.call(inky.dc_pin, GPIO.OUT, initial=GPIO.LOW, pull_up_down=GPIO.PUD_OFF), mock.call(inky.reset_pin, GPIO.OUT, initial=GPIO.HIGH, pull_up_down=GPIO.PUD_OFF), mock.call(inky.busy_pin, GPIO.IN, pull_up_down=GPIO.PUD_OFF) ]) # Check device will been reset GPIO.output.assert_has_calls([ mock.call(inky.reset_pin, GPIO.LOW), mock.call(inky.reset_pin, GPIO.HIGH) ]) # Check API will been opened spidev.SpiDev().open.assert_called_with(0, inky.cs_channel)
def test_init_what_setup_no_gpio(spidev, smbus2): """Test Inky init with a missing RPi.GPIO library.""" from inky import InkyWHAT inky = InkyWHAT('red') with pytest.raises(ImportError): inky.setup()
def try_real_hw(): try: from inky import InkyWHAT inky_display = InkyWHAT('red') inky_display.set_border(inky_display.WHITE) return inky_display except ImportError: return None
def setup_inky(inky_colour): from inky import InkyWHAT inky_display = InkyWHAT(inky_colour) ink_white = inky_display.WHITE #0 ink_black = inky_display.BLACK #1 ink_color = inky_display.YELLOW #2 inky_display.set_border(inky_display.WHITE) w = inky_display.WIDTH h = inky_display.HEIGHT return w, h, ink_black, ink_color #,fonts_dict
def test_init_what_yellow(): """Test initialisation of InkyWHAT with 'yellow' colour choice.""" mockery() from inky import InkyWHAT InkyWHAT('red')
def test_init_what_black(): """Test initialisation of InkyWHAT with 'black' colour choice.""" mockery() from inky import InkyWHAT InkyWHAT('black')
def inky_show(im): im = Image.open(im) im = im.transpose(Image.ROTATE_90) inky_display = InkyWHAT("black") inky_display.set_border(inky_display.WHITE) assert inky_display.WIDTH == 400 assert inky_display.HEIGHT == 300 inky_display.set_image(im) inky_display.show()
def create(quote): inky_display = InkyWHAT("black") inky_display.set_border(inky_display.WHITE) # From https://gist.github.com/jasondilworth56/27764ae8ed2327a34ceebb06e75c30ea from PIL import ImageFont, ImageDraw, Image text = quote[0] author = quote[1] title = quote[2] #font = "/usr/share/fonts/truetype/freefont/FreeMono.ttf" font = "/usr/share/fonts/truetype/freefont/FreeSans.ttf" #font = "/home/pi/.fonts/Roboto-Bold.ttf" #font = "/home/pi/.fonts/Bitter-Regular.otf" #font = "/home/pi/.fonts/ufonts.com_rockwell.ttf" #font = "/home/pi/.fonts/Bookerly/Bookerly-Regular.ttf" #font = "/home/pi/.fonts/static/PlayfairDisplay-Regular.ttf" #font = "/home/pi/.fonts/PlayfairDisplay-VariableFont_wght.ttf" font = "/home/pi/.fonts/FredokaOne-Regular.ttf" #font = "/home/pi/.fonts/AmaticSC-Regular.ttf" img = ImageText((400, 300), background=(255, 255, 255)) img.fill_text_box((20, 20), text, box_width=340, box_height=250, font_filename=font) meta_line = author + ', ' + title #img.write_text( (10, inky_display.HEIGHT - 20), meta_line, font_filename=font) #img.fill_text_box((30, inky_display.HEIGHT - 40), meta_line, box_width=320, box_height=30, font_filename=font) img.write_text_box((30, inky_display.HEIGHT - 30), meta_line, box_width=320, font_filename=font, font_size=12, place='right') filename = '/home/pi/src/coten/images/coten.png' img.save(filename) img = Image.open(filename) img = img.quantize() inky_display.set_image(img) inky_display.set_border(inky_display.WHITE) inky_display.show()
class Inkywhatrbw(Observer): def __init__(self, observable, mode): super().__init__(observable=observable) self.inky_display = InkyWHAT("red") self.inky_display.set_border(self.inky_display.WHITE) self.image = Image.new('P', (SCREEN_WIDTH, SCREEN_HEIGHT)) self.mode = mode def form_image(self, prices): WHITE = self.inky_display.WHITE RED = self.inky_display.RED BLACK = self.inky_display.BLACK screen_draw = ImageDraw.Draw(self.image) screen_draw.rectangle([0,0,SCREEN_WIDTH,SCREEN_HEIGHT],fill=WHITE) if self.mode == "candle": Plot.candle(prices, size=(SCREEN_WIDTH - LEFT_MARGIN, SCREEN_HEIGHT - BOTTOM_MARGIN), position=(LEFT_MARGIN, 0), draw=screen_draw, fill_neg=RED, fill_pos=BLACK) else: last_prices = [x[3] for x in prices] Plot.line(last_prices, size=(SCREEN_WIDTH - LEFT_MARGIN, SCREEN_HEIGHT - BOTTOM_MARGIN), position=(LEFT_MARGIN, 0), draw=screen_draw, fill=BLACK) flatten_prices = [item for sublist in prices for item in sublist] Plot.y_axis_labels(flatten_prices, FONT_SMALL, (0, 0), (LEFT_MARGIN, SCREEN_HEIGHT - BOTTOM_MARGIN - SMALL_FONT_SIZE - 3), draw=screen_draw, fill=BLACK) screen_draw.line([(0, SCREEN_HEIGHT - BOTTOM_MARGIN), (SCREEN_WIDTH, SCREEN_HEIGHT - BOTTOM_MARGIN)], fill=BLACK) screen_draw.line([(LEFT_MARGIN, 0), (LEFT_MARGIN, SCREEN_HEIGHT - BOTTOM_MARGIN)], fill=BLACK) Plot.caption(flatten_prices[len(flatten_prices) - 1], SCREEN_HEIGHT - BOTTOM_MARGIN, SCREEN_WIDTH, FONT_LARGE, screen_draw, fill=BLACK, currency_offset=LEFT_MARGIN, price_offset=LEFT_MARGIN) def update(self, data): self.form_image(data) self.inky_display.set_image(self.image) self.inky_display.show() def close(self): pass
def send_to_display(): # TODO: do only in python... was having some issues with svg2png output_svg_path = os.path.abspath("output.svg") output_png_path = os.path.abspath("output.png") os.system( f"inkscape -z -w 400 -h 300 {output_svg_path} -e {output_png_path}") img = Image.open(output_png_path) pal_img = Image.new("P", (1, 1)) pal_img.putpalette((255, 255, 255, 0, 0, 0, 255, 0, 0) + (0, 0, 0) * 252) img = img.convert("RGB").quantize(palette=pal_img) # send inky_display = InkyWHAT("red") inky_display.set_border(inky_display.RED) inky_display.set_image(img) inky_display.show()
def _init_display(self, color: str, mock=False, display_type='phat'): if mock: from inky import InkyMockPHAT as InkyPHAT from inky import InkyMockWHAT as InkyWHAT else: from inky import InkyPHAT from inky import InkyWHAT if display_type == 'phat': self._display = InkyPHAT(color) self._scale_size = 1.0 self._padding = 2 elif display_type == 'what': self._display = InkyWHAT(color) self._scale_size = 2.20 self._padding = 15 self._display.set_border(self._display.BLACK)
def glyphe(): # Load the icons and rotate them each time. This gives us # a horoscope which rotates during the day, potentially # making us think differently about their meaning print("Starting...") icons = pickle.load( open( "glyphes.pickle", "rb" ) ) print(icons) icons.insert(0, icons.pop()) # put the last element at the front pickle.dump( icons, open( "glyphes.pickle", "wb" ) ) print(icons) total_width = 1947 # to make this 400/300 on resize total_height = 1460 # 2 * 700 + 60 new_image = Image.new('RGBA', (total_width, total_height), 255) offset = ( int(total_width / 2) - 700, 30) new_image.paste( Image.open(dir + 'icons/' + str(icons[0])), offset ) offset = ( int(total_width / 2), 30 ) new_image.paste( Image.open(dir + 'icons/' + icons[1]), offset ) offset = ( int(total_width / 2) - 700, int(new_image.height / 2) + 10) new_image.paste( Image.open(dir + 'icons/' + icons[2]), offset ) offset = ( int(new_image.width / 2), int(new_image.height / 2) + 10 ) new_image.paste( Image.open(dir + 'icons/' + icons[3]), offset ) new_image.convert('P') new_image.save(dir + 'saved/glyphe.png') # Now resize the image to 400x300 and save it for eink display img = Image.open(dir + 'saved/glyphe.png') img = img.resize((400, 300), resample=Image.LANCZOS) img = img.quantize() img.save(dir + 'saved/glyphe-resized.png') from inky import InkyWHAT inky_display = InkyWHAT("black") inky_display.set_border(inky_display.WHITE) inky_display.set_image(img) inky_display.show() print("Done!")
def draw_init(rotate): global icons global image, inky_screen, draw tolog("Initialising the screen...") for icon in glob(ICON_SOURCE): icon_name = icon.split("icon-")[1].replace(".png", "") icon_image = Image.open(icon) icons[icon_name] = icon_image inky_screen = InkyWHAT('black') image = Image.new('P', (EPD_WIDTH, EPD_HEIGHT)) draw = ImageDraw.Draw(image) tolog("...inky screen initialised") return True
def main(): # Initialize Inky wHAT display inky_display = InkyWHAT('black') # Download image and save locally img_data = requests.get(image_url).content with open(img_file, 'wb') as handler: handler.write(img_data) # Open downloaded image img = Image.open(img_file) # Dither downloaded image pal_img = Image.new('P', (1, 1)) pal_img.putpalette((255, 255, 255, 0, 0, 0, 255, 0, 0) + (0, 0, 0) * 252) img = img.convert('RGB').quantize(palette=pal_img) # Display dithered image inky_display.set_image(img) inky_display.show()
def test_init_what_red(spidev, smbus2): """Test initialisation of InkyWHAT with 'red' colour choice.""" from inky import InkyWHAT InkyWHAT('red')
if args.mock: import sys sys.path.insert(0, '../library') from inky import InkyMockPHAT as InkyPHAT from inky import InkyMockWHAT as InkyWHAT else: from inky import InkyWHAT, InkyPHAT colour = args.colour # Set up the correct display and scaling factors if args.type == "phat": inky_display = InkyPHAT(colour) elif args.type == "what": inky_display = InkyWHAT(colour) inky_display.set_border(inky_display.BLACK) # Pick the correct logo image to show depending on display type/colour if args.type == "phat": if colour == 'black': img = Image.open("phat/resources/InkypHAT-212x104-bw.png") else: img = Image.open("phat/resources/InkypHAT-212x104.png") elif args.type == "what": if colour == 'black': img = Image.open("what/resources/InkywHAT-400x300-bw.png") else: img = Image.open("what/resources/InkywHAT-400x300.png")
import os from inky import InkyWHAT from PIL import Image, ImageDraw, ImageFont from font_fredoka_one import FredokaOne from datetime import datetime as dt from twitterbot import * PATH = os.path.dirname(os.path.abspath(__file__)) try: ttf = ImageFont.truetype('./assets/DankMono-Italic.otf', 24) except: ttf = ImageFont.truetype(FredokaOne, 24) # Inky display information inky_display = InkyWHAT("red") black = inky_display.BLACK red = inky_display.RED white = inky_display.WHITE inky_display.rotation = 180 def format_line(font, msg, width): lines = [] w, h = font.getsize(msg) if w <= width: lines.append(msg) else: toks = msg.split() cur_line = '' for tok in toks:
api = twitter.Api(consumer_key=keys.twitter["consumer_key"], consumer_secret=keys.twitter["consumer_secret"], access_token_key=keys.twitter["access_token_key"], access_token_secret=keys.twitter["access_token_secret"], tweet_mode='extended') ################################## ## SET UP THE INKY WHAT DISPLAY ## ################################## # Set the display type and colour # InkyPHAT is for the smaller display and InkyWHAT is for the larger display. # Accepts arguments 'red', 'yellow' or 'black', based on the display you have. # (You can only use 'red' with the red display, and 'yellow' with the yellow; but 'black' works with either). inky = InkyWHAT("yellow") ################### ## SET VARIABLES ## ################### test = args.test if test == True: yellow = "#9B870C" white = "#ffffff" black = "#000000" displayHeight = 300 displayWidth = 400 else: yellow = inky.YELLOW
from math import floor from random import randint from inky import InkyWHAT from PIL import Image, ImageDraw inky_display = InkyWHAT("red") inky_display.set_border(inky_display.WHITE) rules = [18, 22, 26, 30, 45, 57, 60, 62, 73, 75, 82, 86, 89, 90, 101, 102, 105, 109, 110, 124, 126, 129, 131, 135, 137, 145, 146, 149, 150, 153, 154, 161, 165, 167, 181, 182, 190, 193, 195, 210, 214, 218, 225] rulesetNo = rules[randint(0, len(rules) - 1)] ruleset = list(map(int, bin(rulesetNo)[2:].zfill(8)[::-1])) for i in range(0, 8): if ruleset[i] == 1: if randint(0, 100) <= 25: ruleset[i] = 2 print(ruleset) width = inky_display.WIDTH height = inky_display.HEIGHT cellSize = randint(1, 5) rectSize = cellSize - 1 visibleGenerations = floor(height / cellSize) numCells = floor(width / cellSize) cells = [0] * numCells
from inky import InkyWHAT from PIL import Image import sys inkywhat = InkyWHAT('red') #img = Image.open("InkywHAT-400x300.png") img = Image.open("keystrokes_bw.png") inkywhat.set_image(img) inkywhat.show()
#DOCUMENTATIONN #to run on a ras pi, #IF for some reason pip isnt installed $ sudo apt-get install python-pip #otherwise: # pip install qrcode[pil] # NOTE: json is a native library #sudo raspi-config #set SPI to enabled #For the pi hat #sudo pip install inky #we happen to be using a wHat inkywhat = InkyWHAT('black') #NOTE can only have this line on a rasberry pi #defining #version = 1-40 int that specifies size #error_correction = error correction in code (L is %) #fill and back change background of image #box_size is number of pixels each qr box has #border is how many boxes thick the boder should be qr = qrcode.QRCode( version=None, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=4, border=2, )
detail_fontsize_for_track = 30 detail_fontsize_for_artist = 24 detail_fontsize_for_album = 24 detail_fontsize_for_gap_before_stats = 34 detail_fontsize_for_stats = 20 #set font sizes for summary summary_top_gap = 10 summary_fontsize_for_track = 35 summary_gap_between_track_and_artist = 50 summary_fontsize_for_artist = 27 summary_gap_between_artist_and_album = 20 summary_fontsize_for_album = 27 # Set up the correct display and scaling factors inky_display = InkyWHAT(colour) inky_display.set_border(inky_display.WHITE) # find the size of the display display_width = inky_display.WIDTH display_height = inky_display.HEIGHT # this function prints a new line to the image def write_new_line(text_to_write, font_size, alignment="center", reflow=False): global line_y # set font font = ImageFont.truetype(SourceSansProSemibold, font_size) # work out the size of the text
def __init__(self, observable, mode): super().__init__(observable=observable) self.inky_display = InkyWHAT("red") self.inky_display.set_border(self.inky_display.WHITE) self.image = Image.new('P', (SCREEN_WIDTH, SCREEN_HEIGHT)) self.mode = mode
#!/usr/bin/env python3 # written 2020-09-07 by mza # last updated 2020-11-22 by mza # https://learn.pimoroni.com/tutorial/sandyj/getting-started-with-inky-phat from inky import InkyWHAT #inky_display = InkyWHAT("red") inky_display = InkyWHAT("black") inky_display.set_border(inky_display.WHITE) #inky_display.show() width = 400 height = 300 #img = Image.open("x.png") #img = Image.open("time.png") import make_clock import PythonMagick # sudo apt install -y imagemagick python3-pythonmagick import PIL # sudo apt install -y python3-willow resolution = PythonMagick.Geometry(width, height) import time import datetime #composite -size 400x300 -resize 400x300 -gravity center time.svg canvas:white time.png # from https://stackoverflow.com/a/6209894/5728815 import inspect import os filename = inspect.getframeinfo(inspect.currentframe()).filename path = os.path.dirname(os.path.abspath(filename)) #print(path)
def test_init_what_yellow(spidev, smbus2): """Test initialisation of InkyWHAT with 'yellow' colour choice.""" from inky import InkyWHAT InkyWHAT('yellow')
reflowed += word else: line_length = word_length reflowed = reflowed[:-1] + "\n " + word lines = lines + 1 else: truncate = True if truncate: reflowed = reflowed.rstrip() + '..."' else: reflowed = reflowed.rstrip() + '"' return reflowed # Set up the correct display and scaling factors inky_display = InkyWHAT(colour) inky_display.set_border(inky_display.WHITE) # inky_display.set_rotation(180) w = inky_display.WIDTH h = inky_display.HEIGHT # Create a new canvas to draw on img = Image.new("P", (inky_display.WIDTH, inky_display.HEIGHT)) draw = ImageDraw.Draw(img) # Load the fonts font_size = 26 time_size = 18
def test_init_invalid_colour(spidev, smbus2): """Test initialisation of InkyWHAT with an invalid colour choice.""" from inky import InkyWHAT with pytest.raises(ValueError): InkyWHAT('octarine')
def create_pimoroni(quote): import argparse import random import sys from inky import InkyWHAT from PIL import Image, ImageFont, ImageDraw from font_source_serif_pro import SourceSerifProSemibold from font_source_sans_pro import SourceSansProSemibold # Set up the correct display and scaling factors inky_display = InkyWHAT('black') inky_display.set_border(inky_display.WHITE) # inky_display.set_rotation(180) w = inky_display.WIDTH h = inky_display.HEIGHT # Create a new canvas to draw on img = Image.new("P", (inky_display.WIDTH, inky_display.HEIGHT)) draw = ImageDraw.Draw(img) # Load the fonts font_size = 24 author_font_size = 18 quote_font = ImageFont.truetype(SourceSansProSemibold, font_size) author_font = ImageFont.truetype(SourceSerifProSemibold, author_font_size) # The amount of padding around the quote. Note that # a value of 30 means 15 pixels padding left and 15 # pixels padding right. # # Also define the max width and height for the quote. padding = 50 max_width = w - padding max_height = h - padding - author_font.getsize("ABCD ")[1] below_max_length = False # Only pick a quote that will fit in our defined area # once rendered in the font and size defined. while not below_max_length: reflowed = reflow_quote(quote, max_width, quote_font) p_w, p_h = quote_font.getsize(reflowed) # Width and height of quote p_h = p_h * (reflowed.count("\n") + 1) # Multiply through by number of lines if p_h < max_height: below_max_length = True # The quote fits! Break out of the loop. else: font_size = font_size - 1 author_font_size = author_font_size - 1 quote_font = ImageFont.truetype(SourceSansProSemibold, font_size) author_font = ImageFont.truetype(SourceSerifProSemibold, author_font_size) continue # x- and y-coordinates for the top left of the quote quote_x = (w - max_width) / 2 quote_y = ((h - max_height) + (max_height - p_h - author_font.getsize("ABCD ")[1])) / 2 # x- and y-coordinates for the top left of the author author_x = quote_x author_y = quote_y + p_h author = [ '— ' + quote[1] + ', ' + quote[2] ] reflowed_author = reflow_quote(author, max_width, author_font) # Write our quote and author to the canvas draw.multiline_text((quote_x, quote_y), reflowed, fill=inky_display.BLACK, font=quote_font, align="left") draw.multiline_text((author_x, author_y), reflowed_author, fill=inky_display.BLACK, font=author_font, align="right") print(reflowed + "\n" + reflowed_author + "\n") # Display the completed canvas on Inky wHAT inky_display.set_image(img) inky_display.show()
# rotate image if necessary due to power cord # img = img.rotate(180, expand=True) inky_display.set_image(inky_image) inky_display.show() if __name__ == "__main__": import argparse from font_fredoka_one import FredokaOne parser = argparse.ArgumentParser(description="Write text to inky") parser.add_argument("--count", type=int, default=30) parser.add_argument("--font-size", type=int, default=26) parser.add_argument("--clear", action="store_true", default=False) args = parser.parse_args() logger = logging.getLogger("eink") logger.setLevel("INFO") inky_display = InkyWHAT("black") if args.clear: logger.info("Clearing Display") clear(inky_display) exit(0) font = ImageFont.truetype(FredokaOne, args.font_size) text = "abcd efgh " * args.count lines = fit_lines(text, font, inky_display.WIDTH) image = draw_lines(inky_display, lines, font, origin=(15, 15)) show(inky_display, image)
parser.add_argument("--clear", action="store_true", default=False) parser.add_argument("--draw", action="store_true", default=False) parser.add_argument("--weather", action="store_true", default=False) parser.add_argument("--write", action="store_true", default=False) parser.add_argument("--border", action="store_true", default=False) parser.add_argument("--font", default="Gidole-Regular") parser.add_argument("--font-size", type=int, default=25) parser.add_argument("--font-padding", type=int, default=5) parser.add_argument("--filename", type=str, help="resources/matisse.png|promenade_des_anglais.jpg") args = parser.parse_args() logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', level=logging.INFO) inky_display = InkyWHAT("black") if args.border: inky_display.set_border(inky_display.BLACK) if args.clear: logging.info("Clearing Inky") clear(inky_display) if args.draw and args.filename: logging.info(f"Drawing Inky {args.filename}") image = prepare(inky_display, args.filename) draw(inky_display, image) if args.write: logging.info(f"Writing Inky lines from stdin")