commit
0059dda861
Binary file not shown.
Binary file not shown.
@ -0,0 +1,82 @@
|
||||
from PIL import Image, ImageDraw, ImageFont, ImageOps
|
||||
import re
|
||||
import time
|
||||
import widget
|
||||
import argparse
|
||||
try:
|
||||
import epd7in5b
|
||||
testMode = False
|
||||
except:
|
||||
testMode = True
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description="EinkPaper display")
|
||||
parser.add_argument('-t', '--test', help='enable test mode', action='store_true')
|
||||
args = parser.parse_args()
|
||||
if args.test:
|
||||
testMode = True
|
||||
|
||||
print("RUNNING IN TESTMODE: "+str(testMode))
|
||||
|
||||
if not testMode:
|
||||
epd = epd7in5b.EPD()
|
||||
epd.init()
|
||||
|
||||
width = 640
|
||||
height = 384
|
||||
cwidth = int(round(width/3))
|
||||
cheight = int(round(height/3))
|
||||
|
||||
image_yellow = Image.new('1', (width, height), 255) # 255: clear the frame
|
||||
draw_yellow = ImageDraw.Draw(image_yellow)
|
||||
image_black = Image.new('1', (width, height), 255) # 255: clear the frame
|
||||
draw_black = ImageDraw.Draw(image_black)
|
||||
|
||||
#str = """abcdefghijkmnop test test test hello Current temperature: 17C, Feels like: 20C Traffic is light. Should take 21 minutes to get to work. BREAKING NEWS: news headline goes here. To do: 1) Fix MHDoorLock 2) Work on waveshare epaper device"""
|
||||
str1 = """Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."""
|
||||
str2 = """Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
||||
|
||||
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
|
||||
|
||||
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."""
|
||||
str3 = """But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"""
|
||||
strList = []
|
||||
strList.append(str1)
|
||||
strList.append(str2)
|
||||
strList.append(str3)
|
||||
|
||||
def initWidgets():
|
||||
widgetList = []
|
||||
widgetList.append(widget.TextWidget(cwidth, cheight, 0, 0, 1, 2, str1))
|
||||
widgetList.append(widget.TextWidget(cwidth, cheight, 1, 0, 2, 1, str2))
|
||||
#widgetList.append(widget.ImageWidget(cwidth, cheight, 2, 1, 1, 1, "mono", "faces.jpg"))
|
||||
widgetList.append(widget.ImageWidget(cwidth, cheight, 1, 1, 2, 2, "mono", "img1.jpg"))
|
||||
widgetList.append(widget.ImageWidget(cwidth, cheight, 0, 2, 1, 1, "mono", "img1.jpg"))
|
||||
return widgetList
|
||||
|
||||
def drawWidget(w):
|
||||
coordX = w.cellX*cwidth
|
||||
coordY = w.cellY*cheight
|
||||
image_black.paste(w.image_black, (coordX, coordY))
|
||||
image_yellow.paste(w.image_yellow, (coordX, coordY))
|
||||
|
||||
def render(index):
|
||||
for widg in widgetList:
|
||||
drawWidget(widg)
|
||||
if not testMode:
|
||||
print("pushing to display frame")
|
||||
epd.display_frame(epd.get_frame_buffer(image_black),epd.get_frame_buffer(image_yellow))
|
||||
print("done")
|
||||
else:
|
||||
print("saving canvas images")
|
||||
image_black.save("imgBlack.bmp")
|
||||
image_yellow.save("imgYellow.bmp")
|
||||
print("done")
|
||||
|
||||
widgetList = initWidgets()
|
||||
|
||||
i = 0
|
||||
while(True):
|
||||
render(i)
|
||||
i = (i + 1)%3
|
||||
time.sleep(10)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 94 KiB |
@ -0,0 +1,204 @@
|
||||
##
|
||||
# @filename : epd7in5.py
|
||||
# @brief : Implements for Dual-color e-paper library
|
||||
# @author : Yehui from Waveshare
|
||||
#
|
||||
# Copyright (C) Waveshare July 10 2017
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documnetation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
|
||||
import epdif
|
||||
import Image
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
# Display resolution
|
||||
EPD_WIDTH = 640
|
||||
EPD_HEIGHT = 384
|
||||
|
||||
# EPD7IN5 commands
|
||||
PANEL_SETTING = 0x00
|
||||
POWER_SETTING = 0x01
|
||||
POWER_OFF = 0x02
|
||||
POWER_OFF_SEQUENCE_SETTING = 0x03
|
||||
POWER_ON = 0x04
|
||||
POWER_ON_MEASURE = 0x05
|
||||
BOOSTER_SOFT_START = 0x06
|
||||
DEEP_SLEEP = 0x07
|
||||
DATA_START_TRANSMISSION_1 = 0x10
|
||||
DATA_STOP = 0x11
|
||||
DISPLAY_REFRESH = 0x12
|
||||
IMAGE_PROCESS = 0x13
|
||||
LUT_FOR_VCOM = 0x20
|
||||
LUT_BLUE = 0x21
|
||||
LUT_WHITE = 0x22
|
||||
LUT_GRAY_1 = 0x23
|
||||
LUT_GRAY_2 = 0x24
|
||||
LUT_RED_0 = 0x25
|
||||
LUT_RED_1 = 0x26
|
||||
LUT_RED_2 = 0x27
|
||||
LUT_RED_3 = 0x28
|
||||
LUT_XON = 0x29
|
||||
PLL_CONTROL = 0x30
|
||||
TEMPERATURE_SENSOR_COMMAND = 0x40
|
||||
TEMPERATURE_CALIBRATION = 0x41
|
||||
TEMPERATURE_SENSOR_WRITE = 0x42
|
||||
TEMPERATURE_SENSOR_READ = 0x43
|
||||
VCOM_AND_DATA_INTERVAL_SETTING = 0x50
|
||||
LOW_POWER_DETECTION = 0x51
|
||||
TCON_SETTING = 0x60
|
||||
TCON_RESOLUTION = 0x61
|
||||
SPI_FLASH_CONTROL = 0x65
|
||||
REVISION = 0x70
|
||||
GET_STATUS = 0x71
|
||||
AUTO_MEASUREMENT_VCOM = 0x80
|
||||
READ_VCOM_VALUE = 0x81
|
||||
VCM_DC_SETTING = 0x82
|
||||
|
||||
class EPD:
|
||||
def __init__(self):
|
||||
self.reset_pin = epdif.RST_PIN
|
||||
self.dc_pin = epdif.DC_PIN
|
||||
self.busy_pin = epdif.BUSY_PIN
|
||||
self.width = EPD_WIDTH
|
||||
self.height = EPD_HEIGHT
|
||||
|
||||
def digital_write(self, pin, value):
|
||||
epdif.epd_digital_write(pin, value)
|
||||
|
||||
def digital_read(self, pin):
|
||||
return epdif.epd_digital_read(pin)
|
||||
|
||||
def delay_ms(self, delaytime):
|
||||
epdif.epd_delay_ms(delaytime)
|
||||
|
||||
def send_command(self, command):
|
||||
self.digital_write(self.dc_pin, GPIO.LOW)
|
||||
# the parameter type is list but not int
|
||||
# so use [command] instead of command
|
||||
epdif.spi_transfer([command])
|
||||
|
||||
def send_data(self, data):
|
||||
self.digital_write(self.dc_pin, GPIO.HIGH)
|
||||
# the parameter type is list but not int
|
||||
# so use [data] instead of data
|
||||
epdif.spi_transfer([data])
|
||||
|
||||
def init(self):
|
||||
if (epdif.epd_init() != 0):
|
||||
return -1
|
||||
self.reset()
|
||||
self.send_command(POWER_SETTING)
|
||||
self.send_data(0x37)
|
||||
self.send_data(0x00)
|
||||
self.send_command(PANEL_SETTING)
|
||||
self.send_data(0xCF)
|
||||
self.send_data(0x08)
|
||||
self.send_command(BOOSTER_SOFT_START)
|
||||
self.send_data(0xc7)
|
||||
self.send_data(0xcc)
|
||||
self.send_data(0x28)
|
||||
self.send_command(POWER_ON)
|
||||
self.wait_until_idle()
|
||||
self.send_command(PLL_CONTROL)
|
||||
self.send_data(0x3c)
|
||||
self.send_command(TEMPERATURE_CALIBRATION)
|
||||
self.send_data(0x00)
|
||||
self.send_command(VCOM_AND_DATA_INTERVAL_SETTING)
|
||||
self.send_data(0x77)
|
||||
self.send_command(TCON_SETTING)
|
||||
self.send_data(0x22)
|
||||
self.send_command(TCON_RESOLUTION)
|
||||
self.send_data(0x02) #source 640
|
||||
self.send_data(0x80)
|
||||
self.send_data(0x01) #gate 384
|
||||
self.send_data(0x80)
|
||||
self.send_command(VCM_DC_SETTING)
|
||||
self.send_data(0x1E) #decide by LUT file
|
||||
self.send_command(0xe5) #FLASH MODE
|
||||
self.send_data(0x03)
|
||||
|
||||
def wait_until_idle(self):
|
||||
while(self.digital_read(self.busy_pin) == 0): # 0: busy, 1: idle
|
||||
self.delay_ms(100)
|
||||
|
||||
def reset(self):
|
||||
self.digital_write(self.reset_pin, GPIO.LOW) # module reset
|
||||
self.delay_ms(200)
|
||||
self.digital_write(self.reset_pin, GPIO.HIGH)
|
||||
self.delay_ms(200)
|
||||
|
||||
def get_frame_buffer(self, image):
|
||||
buf = [0xFF] * (self.width * self.height / 8)
|
||||
# Set buffer to value of Python Imaging Library image.
|
||||
# Image must be in mode L.
|
||||
image_grayscale = image.convert('1')
|
||||
imwidth, imheight = image_grayscale.size
|
||||
if imwidth != self.width or imheight != self.height:
|
||||
raise ValueError('Image must be same dimensions as display \
|
||||
({0}x{1}).' .format(self.width, self.height))
|
||||
|
||||
pixels = image_grayscale.load()
|
||||
for y in range(self.height):
|
||||
for x in range(self.width):
|
||||
# Set the bits for the column of pixels at the current position.
|
||||
if pixels[x, y] == 0:
|
||||
buf[(x + y * self.width) / 8] &= ~(0x80 >> (x % 8))
|
||||
return buf
|
||||
|
||||
def display_frame(self, frame_buffer_black, frame_buffer_red):
|
||||
self.send_command(DATA_START_TRANSMISSION_1)
|
||||
for i in range(0, self.width / 8 * self.height):
|
||||
temp1 = frame_buffer_black[i]
|
||||
temp2 = frame_buffer_red[i]
|
||||
j = 0
|
||||
while (j < 8):
|
||||
if ((temp2 & 0x80) == 0x00):
|
||||
temp3 = 0x04 #red
|
||||
elif ((temp1 & 0x80) == 0x00):
|
||||
temp3 = 0x00 #black
|
||||
else:
|
||||
temp3 = 0x03 #white
|
||||
|
||||
temp3 = (temp3 << 4) & 0xFF
|
||||
temp1 = (temp1 << 1) & 0xFF
|
||||
temp2 = (temp2 << 1) & 0xFF
|
||||
j += 1
|
||||
if((temp2 & 0x80) == 0x00):
|
||||
temp3 |= 0x04 #red
|
||||
elif ((temp1 & 0x80) == 0x00):
|
||||
temp3 |= 0x00 #black
|
||||
else:
|
||||
temp3 |= 0x03 #white
|
||||
temp1 = (temp1 << 1) & 0xFF
|
||||
temp2 = (temp2 << 1) & 0xFF
|
||||
self.send_data(temp3)
|
||||
j += 1
|
||||
self.send_command(DISPLAY_REFRESH)
|
||||
self.delay_ms(100)
|
||||
self.wait_until_idle()
|
||||
|
||||
def sleep(self):
|
||||
self.send_command(POWER_OFF)
|
||||
self.wait_until_idle()
|
||||
self.send_command(DEEP_SLEEP)
|
||||
self.send_data(0xa5)
|
||||
|
||||
### END OF FILE ###
|
||||
|
||||
Binary file not shown.
@ -0,0 +1,63 @@
|
||||
##
|
||||
# @filename : epdif.py
|
||||
# @brief : EPD hardware interface implements (GPIO, SPI)
|
||||
# @author : Yehui from Waveshare
|
||||
#
|
||||
# Copyright (C) Waveshare July 10 2017
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documnetation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
|
||||
import spidev
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
# Pin definition
|
||||
RST_PIN = 17
|
||||
DC_PIN = 25
|
||||
CS_PIN = 8
|
||||
BUSY_PIN = 24
|
||||
|
||||
# SPI device, bus = 0, device = 0
|
||||
SPI = spidev.SpiDev(0, 0)
|
||||
|
||||
def epd_digital_write(pin, value):
|
||||
GPIO.output(pin, value)
|
||||
|
||||
def epd_digital_read(pin):
|
||||
return GPIO.input(BUSY_PIN)
|
||||
|
||||
def epd_delay_ms(delaytime):
|
||||
time.sleep(delaytime / 1000.0)
|
||||
|
||||
def spi_transfer(data):
|
||||
SPI.writebytes(data)
|
||||
|
||||
def epd_init():
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setwarnings(False)
|
||||
GPIO.setup(RST_PIN, GPIO.OUT)
|
||||
GPIO.setup(DC_PIN, GPIO.OUT)
|
||||
GPIO.setup(CS_PIN, GPIO.OUT)
|
||||
GPIO.setup(BUSY_PIN, GPIO.IN)
|
||||
SPI.max_speed_hz = 2000000
|
||||
SPI.mode = 0b00
|
||||
return 0;
|
||||
|
||||
### END OF FILE ###
|
||||
|
After Width: | Height: | Size: 171 KiB |
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
@ -0,0 +1,26 @@
|
||||
import epd7in5b
|
||||
from PIL import Image, ImageDraw, ImageFont, ImageOps
|
||||
import re
|
||||
from renderer import Rend
|
||||
|
||||
WIDTH = 640
|
||||
HEIGHT = 384
|
||||
|
||||
def main():
|
||||
epd = epd7in5b.EPD()
|
||||
epd.init()
|
||||
|
||||
rend = Rend()
|
||||
rend.render()
|
||||
|
||||
print("start display frame")
|
||||
epd.display_frame(epd.get_frame_buffer(rend.image_black),epd.get_frame_buffer(rend.image_yellow))
|
||||
print("finish display frame")
|
||||
|
||||
#display images
|
||||
#frame_black = epd.get_frame_buffer(Image.open('black.bmp'))
|
||||
#frame_yellow = epd.get_frame_buffer(Image.open('red2.bmp'))
|
||||
#epd.display_frame(frame_black, frame_yellow)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@ -0,0 +1,7 @@
|
||||
Run EinkPaper.py to start the program. To run in test mode, add argument -t or --test.
|
||||
Test mode will save generated images to the working directory rather than export them to an external display.
|
||||
Test mode will auto run if no external display package is detected.
|
||||
|
||||
EinkPaper.py will construct widget classes from widgets.py. Widgets are constructed in the initWidgets() function in EinkPaper.py.
|
||||
|
||||
The image widget is currently set to resize (to fit the whole image on the widget w/ no cropping), then to either monochrome or greyscale dither the image as specified in initWidgets(). The zoom function is currently broken and to be fixed.
|
||||
@ -0,0 +1,164 @@
|
||||
from __future__ import division
|
||||
from PIL import Image, ImageDraw, ImageFont, ImageOps
|
||||
import re
|
||||
|
||||
def textBox(text, font, position, limits, colour, draw_black):
|
||||
str = ""
|
||||
limit = [0, 0]
|
||||
limit[0] = limits[0] - position[0]
|
||||
limit[1] = limits[1] - position[1]
|
||||
words = text.split(" ")
|
||||
i = 0 #index of first word
|
||||
sizex, sizey = draw_black.multiline_textsize(str, font) #size of the textbox
|
||||
#while more words to be added to string AND string textbox height < height limit
|
||||
for word in words:
|
||||
sizex, sizey = draw_black.multiline_textsize(str + word, font)
|
||||
sizex2, sizey2 = draw_black.multiline_textsize(str, font)
|
||||
if sizex < limit[0]: #if width of gen textbox < width limit
|
||||
str += word + " "
|
||||
else:
|
||||
sizex, sizey = draw_black.multiline_textsize(str + "\n" + word, font)
|
||||
if(sizey > limit[1]):
|
||||
break
|
||||
else:
|
||||
str = str.rstrip(" ")
|
||||
str += "\n" + word + " "
|
||||
draw_black.text(position, str, font = font, fill = 0)
|
||||
|
||||
|
||||
def putImage(imagepath, maskpath, position, colour):
|
||||
img = Image.open(imagepath)
|
||||
mask = Image.open(maskpath).convert(mode='1')
|
||||
if colour is "black":
|
||||
image_black.paste(img, position, mask)
|
||||
if colour is "yellow":
|
||||
image_yellow.paste(img, position, mask)
|
||||
black_invert = ImageOps.invert(image_black.convert('L'))
|
||||
draw_yellow.bitmap((0,0), black_invert, 255)
|
||||
|
||||
class TextWidget():
|
||||
#this example widget will have a set size: 3x1 cells (one column)
|
||||
#an instance of this widget class can be created and pasted to canvas
|
||||
def __init__(self, cwidth, cheight, x = 0, y = 0, width = 1, height = 1, str = ""):
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.wt = cwidth*width
|
||||
self.ht = cheight*height
|
||||
self.cellX = x
|
||||
self.cellY = y
|
||||
self.image_yellow = Image.new('1', (self.wt, self.ht), 255) #255: clear the frame
|
||||
self.draw_yellow = ImageDraw.Draw(self.image_yellow)
|
||||
self.image_black = Image.new('1', (self.wt, self.ht), 255) #255: clear the frame
|
||||
self.draw_black = ImageDraw.Draw(self.image_black)
|
||||
self.font = ImageFont.truetype('DejaVuSans.ttf', 16)
|
||||
self.updateWidget(str)
|
||||
|
||||
def drawText(self, str):
|
||||
#define parameters for text placement
|
||||
position = (0,0)
|
||||
limit = (self.wt, self.ht)
|
||||
#write the string in the widget
|
||||
textBox(str, self.font, position, limit, "black", self.draw_black)
|
||||
|
||||
def saveImages(self):
|
||||
print("saving widget images")
|
||||
self.image_black.save("imgBlackWidget.bmp")
|
||||
self.image_yellow.save("imgYellowWidget.bmp")
|
||||
|
||||
def updateWidget(self, str):
|
||||
self.draw_black.rectangle((0, 0, self.wt, self.ht), fill=255)
|
||||
self.draw_yellow.rectangle((0, 0, self.wt, self.ht), fill=255)
|
||||
self.drawText(str)
|
||||
self.saveImages()
|
||||
|
||||
class ImageWidget():
|
||||
#this widget displays an image
|
||||
#needs to recieve an image file as input. Then resize and convert to monochrome.
|
||||
def __init__(self, cwidth, cheight, x = 0, y = 0, width = 1, height = 1, mode = "mono", img = ""):
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.wt = cwidth*width
|
||||
self.ht = cheight*height
|
||||
self.cellX = x
|
||||
self.cellY = y
|
||||
self.image_yellow = Image.new('1', (self.wt, self.ht), 255) #255: clear the frame
|
||||
self.draw_yellow = ImageDraw.Draw(self.image_yellow)
|
||||
self.image_black = Image.new('1', (self.wt, self.ht), 255) #255: clear the frame
|
||||
self.draw_black = ImageDraw.Draw(self.image_black)
|
||||
self.mode = mode
|
||||
self.updateWidget(Image.open(img))
|
||||
|
||||
def resizeImg(self, img):
|
||||
#scale image down until whole image fits inside the cell
|
||||
iRatio = img.size[0]/img.size[1] #image ratio
|
||||
cRatio = self.wt/self.ht #canvas ratio
|
||||
if cRatio > iRatio: #height is limiting dimension
|
||||
fixedImg = img.resize((int(self.ht*iRatio), self.ht))
|
||||
print(" limited by height")
|
||||
return fixedImg
|
||||
if cRatio < iRatio: #width is limiting dimension
|
||||
fixedImg = img.resize((self.wt, int(self.wt/iRatio)))
|
||||
print(" limited by width")
|
||||
return fixedImg
|
||||
fixedImg = img
|
||||
print(" ratios are equal, not limited")
|
||||
return fixedImg
|
||||
|
||||
def zoomImg(self, img):
|
||||
#enlarge the image and crop to fill the widget canvas
|
||||
iRatio = img.size[0]/img.size[1] #image ratio
|
||||
cRatio = self.wt/self.ht #canvas ratio
|
||||
if cRatio > iRatio:
|
||||
print("new sizes as calcd in resize: "+str(self.wt)+" "+str(self.wt/iRatio))
|
||||
fixedImg = img.resize((self.wt, int(self.wt/iRatio))) #width = wt, calc new height w/ ratio
|
||||
offset = 0.5*(fixedImg.size[1] - self.ht) #centre by height
|
||||
cropped = fixedImg.crop((0, offset, self.wt, offset+self.ht))
|
||||
cropped.load()
|
||||
print("zoomed to fill height")
|
||||
return cropped
|
||||
if cRatio < iRatio:
|
||||
fixedImg = img.resize((int(self.ht*iRatio), self.ht)) #height = ht, calc new width w/ ratio
|
||||
offset = 0.5*(fixedImg.size[0] - self.wt) #centre by width
|
||||
cropped = fixedImg.crop((offset, 0, offset+self.wt, self.ht))
|
||||
cropped.load()
|
||||
print("zoomed to fill width")
|
||||
return cropped
|
||||
print("not zoomed")
|
||||
return img.resize((self.wt, self.ht))
|
||||
|
||||
def threshold(self, val):
|
||||
if(val>100):
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def bwImg(self, img):
|
||||
if self.mode is "mono":
|
||||
return img.convert('L').point(self.threshold, '1')
|
||||
if self.mode is "dither":
|
||||
return img.convert(mode='1')
|
||||
|
||||
def pasteImg(self, img):
|
||||
iRatio = img.size[0]/img.size[1] #image ratio
|
||||
cRatio = self.wt/self.ht #canvas ratio
|
||||
if cRatio > iRatio: #needs to be centred horizontally
|
||||
offset = int(0.5*(self.wt - img.size[0]))
|
||||
self.image_black.paste(img, (offset, 0))
|
||||
if cRatio < iRatio: #needs to be centred vertically
|
||||
offset = int(0.5*(self.ht - img.size[1]))
|
||||
self.image_black.paste(img, (0, offset))
|
||||
|
||||
def saveImages(self):
|
||||
print("saving widget images")
|
||||
self.image_black.save("imgBlackWidget.bmp")
|
||||
self.image_yellow.save("imgYellowWidget.bmp")
|
||||
|
||||
def updateWidget(self, img):
|
||||
rsImg = self.resizeImg(img)
|
||||
rsImg.save("rsImg.bmp")
|
||||
newImg = self.bwImg(rsImg)
|
||||
newImg.save("bwImg.bmp")
|
||||
print(" Dimensions are now: "+str(newImg.size[0])+"x"+str(newImg.size[1]))
|
||||
print(" Dimensions of widget canvas: "+str(self.wt)+"x"+str(self.ht))
|
||||
self.pasteImg(newImg)
|
||||
self.saveImages()
|
||||
Binary file not shown.
Loading…
Reference in new issue