import time
from rpi_ws281x import *
import argparse
import RPi.GPIO as GPIO
from PIL import Image
LED_COUNT = 128 LED_PIN = 18 LED_FREQ_HZ = 800000 LED_DMA = 10 LED_BRIGHTNESS = 255 LED_INVERT = False LED_CHANNEL = 0
BUTTON_CHANNEL = 19
def UnColor(color):
return ((color >> 24) & 0xFF , (color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF)
def lightpaint(filename, frame_rate=100, column_rate=1, reverse_x=False, reverse_y=False, loop=False):
img = Image.open(filename).convert("RGB")
if(img.size[1] < LED_COUNT):
raise Exception("Image height is smaller than led strip size. Required height = {}".format(LED_COUNT))
elif(img.size[1] > LED_COUNT):
print "Resizing image"
new_width = LED_COUNT * img.size[0] / img.size[1]
img = img.resize((new_width, LED_COUNT), Image.ANTIALIAS)
input_image = img.load()
image_width = img.size[0]
column = [0 for x in range(image_width)]
for x in range(image_width):
column[x] = [None] * (LED_COUNT)
for x in range(image_width):
for y in range(LED_COUNT):
value = input_image[x, y]
column[x][y] = Color(value[1], value[0], value[2])
while True:
if not loop:
print("Waiting for button to be pressed")
GPIO.wait_for_edge(BUTTON_CHANNEL, GPIO.FALLING)
time.sleep(0.5)
x_range = range(image_width)
if reverse_x:
x_range.reverse()
y_range = range(LED_COUNT)
if reverse_y:
y_range.reverse()
for x in x_range:
led_pos = 0
for y in y_range:
strip.setPixelColor(led_pos, column[x][y])
led_pos += 1
strip.show()
time.sleep(column_rate / 1000.0)
time.sleep(frame_rate / 1000.0)
def colorWipe(strip, color, wait_ms=50):
for i in range(strip.numPixels()):
strip.setPixelColor(i, color)
strip.show()
time.sleep(wait_ms/1000.0)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-c', '--clear', action='store_true', help='clear the display on exit')
parser.add_argument('-f', '--file', action='store', help='Filename to display')
parser.add_argument('-r', '--frame_rate', action='store', default=100, help='Rate between each frame. Defines how fast a new frame is displayed')
parser.add_argument('-l', '--column_rate', action='store', default=1, help='Rate between each column. Defines how fast or slow you need to move the stick')
parser.add_argument('-b', '--brightness', action='store', default=10, help='Brightness of the LED. Set to 0 for darkest and 255 for brightest')
parser.add_argument('-x', '--reverse_x', action='store_true', help='Reverse the image in the X direction')
parser.add_argument('-y', '--reverse_y', action='store_true', help='Reverse the image in the Y direction')
parser.add_argument('--loop', action='store_true', help='Play frames in a loop')
args = parser.parse_args()
strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, args.brightness, LED_CHANNEL)
strip.begin()
GPIO.setmode(GPIO.BOARD)
GPIO.setup(BUTTON_CHANNEL, GPIO.IN, pull_up_down=GPIO.PUD_UP)
print ('Press Ctrl-C to quit.')
if not args.clear:
print('Use "-c" argument to clear LEDs on exit')
try:
while True:
print ('Lightpaint.')
lightpaint(args.file, float(args.frame_rate), float(args.column_rate), args.reverse_x, args.reverse_y, args.loop)
except KeyboardInterrupt:
if args.clear:
colorWipe(strip, Color(0,0,0), 10)
GPIO.cleanup()