Skip to content

Instantly share code, notes, and snippets.

@joeycastillo
Created August 1, 2020 20:12
Show Gist options
  • Save joeycastillo/0a90f56681329729f3a56a95af4495ab to your computer and use it in GitHub Desktop.
Save joeycastillo/0a90f56681329729f3a56a95af4495ab to your computer and use it in GitHub Desktop.
Display real-time GOES-East imagery on a Waveshare 7-color EPD
# Based on Waveshare's epd5in65f.py demo. Copyright notice at end.
import sys
import os
picdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'pic')
libdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'lib')
if os.path.exists(libdir):
sys.path.append(libdir)
import logging
from waveshare_epd import epd5in65f
import time
from PIL import Image, ImageEnhance, ImageDraw
import requests
from io import BytesIO
# from https://stackoverflow.com/questions/29433243/convert-image-to-specific-palette-using-pil-without-dithering
def quantizetopalette(silf, palette, dither=False):
'''Convert an RGB or L mode image to use a given P image's palette.'''
silf.load()
palette.load()
if palette.mode != 'P':
raise ValueError('bad mode for palette image')
if silf.mode != 'RGB' and silf.mode != 'L':
raise ValueError(
'only RGB or L mode images can be quantized to a palette'
)
im = silf.im.convert('P', 1 if dither else 0, palette.im)
try:
return silf._new(im)
except AttributeError:
return silf._makeself(im)
logging.basicConfig(level=logging.DEBUG)
try:
response = requests.get('https://cdn.star.nesdis.noaa.gov/GOES16/ABI/FD/GEOCOLOR/5424x5424.jpg')
img = Image.open(BytesIO(response.content))
# blow out the saturation
converter = ImageEnhance.Color(img)
img = converter.enhance(3)
# cover up the logos and timestamp area
draw = ImageDraw.Draw(img)
draw.rectangle([0, 5376, 5424, 5424], 0, 0)
draw.rectangle([0, 5000, 400, 5424], 0, 0)
img = img.resize((448, 448))
# ugly hack: the green ink is very dark. lighten greens and add some yellow.
for x in range(img.width):
for y in range(img.height):
pixel = img.getpixel((x,y))
if pixel[1] > pixel[0] and pixel[1] > pixel[2]:
img.putpixel( (x,y), (pixel[1] >> 1, (pixel[1] >> 2) + pixel[1], pixel[2] >> 1))
# expand image to fill screen
expanded = Image.new(img.mode, (600, 448))
expanded.paste(img, (76, 2))
# dither to 7-color palette
palettedata = [0x00, 0x00, 0x00,
0xff, 0xff, 0xff,
0x00, 0xff, 0x00,
0x00, 0x00, 0xff,
0xff, 0x00, 0x00,
0xff, 0xff, 0x00,
0xff, 0x80, 0x00,
]
for i in range(0, 249 * 3):
palettedata.append(0)
palimage = Image.new('P', (600, 448))
palimage.putpalette(palettedata)
newimage = quantizetopalette(expanded, palimage, dither=True)
newimage = newimage.rotate(90, expand=True)
# clear screen and display image
epd = epd5in65f.EPD()
logging.info('init...')
epd.init()
logging.info('clear...')
epd.Clear()
logging.info('displaying...')
epd.display(epd.getbuffer(newimage))
logging.info('Done!')
time.sleep(3)
logging.info('sleeping...')
epd.sleep()
except IOError as e:
logging.info(e)
except KeyboardInterrupt:
logging.info('ctrl + c:')
epd5in65f.epdconfig.module_exit()
exit()
# *****************************************************************************
# * | File : epd5in65f.py
# * | Author : Waveshare team
# * | Function : Electronic paper driver
# * | Info :
# *----------------
# * | This version: V1.0
# * | Date : 2020-03-02
# # | Info : python demo
# -----------------------------------------------------------------------------
# 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.
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment