from PIL import Image, ImageDraw, ImageFont import socket import binascii import io import time import re import numpy as np class FlipdotSender(object): ''' classdocs ''' C_BLACK = 0 C_WHITE = 255 global threadrunning threadrunning=False lastimgmap = [] def __init__(self, udphost, udpport, img_size=(80,16), font_size=9, font_size_scroll=12, font_offset1=(0,0), font_offset2=(0,8), #font_family='/usr/share/fonts/gnu-free/FreeMono.ttf', font_family='/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf', #font_family='/usr/share/fonts/truetype/freefont/FreeMono.ttf', chars_per_line=11): ''' Constructor ''' self._udphost = udphost if not type(udpport) is int or udpport > 65536: raise TypeError('port has to be int and > 65536 !!') self._udpport = udpport self._img_size = img_size self._font_size = font_size self._font_size_scroll = font_size_scroll self._font_offset1 = font_offset1 self._font_offset2 = font_offset2 self._font_family = font_family self._chars_per_line = chars_per_line self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) def stopAnimation(self): global threadrunning threadrunning=False #tried to stop a running animation def _list2byte(self, l): byte = 0 i = 0 for i in range(8): byte += 2**(7-i) if l[i] else 0 return byte def _array2packet(self, a): return [self._list2byte(a[i*8:i*8+8]) for i in range(int(len(a)/8))] ''' def _send(self, image): #old function, backup imgmap = [] for pixel in image.getdata(): r, g, b, a = pixel if r == FlipdotSender.C_WHITE: imgmap.append(1) else: imgmap.append(0) lastimgmap=imgmap packet = self._array2packet(imgmap) self._sock.sendto(bytes(packet), (self._udphost, self._udpport))''' def _send(self, image,fadespeed=0): #changes slowly 'fadespeed'-pixels at a time global threadrunning #if fadespeed=0 -> change instant. #time to change= 1280/25*0.2 imgmap = [] for pixel in image.getdata(): r, g, b, a = pixel if r == FlipdotSender.C_WHITE: imgmap.append(1) else: imgmap.append(0) imgmaptmp=FlipdotSender.lastimgmap if fadespeed>0: threadrunning=True #diff=np.sum(np.array(imgmaptmp) != np.array(imgmap)) #different pixels pixelchangeind=np.arange(self._img_size[0]*self._img_size[1]) np.random.shuffle(pixelchangeind) for _i,ind in enumerate(pixelchangeind): if threadrunning==False: break #stop this for if ind1: draw.text(self._font_offset2, splitted_text[1], font=font, fill=FlipdotSender.C_WHITE) self._send(image,fadespeed) def send_textFull(self, text,fadespeed=0): image = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK) draw = ImageDraw.Draw(image) draw.fontmode = "1" # No AA l=1000 #init very high splitpoint=40 #very high currentfontsize=12+1 #init with max font size font = ImageFont.truetype(self._font_family, currentfontsize) while(l>80): #while text too long and font not too small if currentfontsize>8: currentfontsize=currentfontsize-1 #reduce size and try if fits else: #if fontsize too small, try cutting sentence (2 lines) splitpoint=splitpoint-1 font = ImageFont.truetype(self._font_family, currentfontsize) l=draw.textsize(text[0:splitpoint], font=font)[0] print("Textlength="+str(l)+" split="+str(splitpoint)) if splitpoint==40: #not splitted draw.text((0,int((16-currentfontsize)/2) ), text, font=font, fill=FlipdotSender.C_WHITE) else: draw.text((0,-1), text[0:splitpoint], font=font, fill=FlipdotSender.C_WHITE) draw.text((0,-1+currentfontsize), text[splitpoint:], font=font, fill=FlipdotSender.C_WHITE) self._send(image,fadespeed) def send_marquee(self, str, speed=3): global threadrunning threadrunning=True offset = self._img_size[0] font = ImageFont.truetype(self._font_family, self._font_size_scroll) while offset >= -font.getsize(str)[0]-speed and threadrunning==True: image = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK) draw = ImageDraw.Draw(image) draw.fontmode = "1" # No AA draw.text((offset,0), str, font=font, fill=FlipdotSender.C_WHITE) self._send(image) offset -= speed time.sleep(0.15) threadrunning=False def send_img(self, img): background = Image.new("RGBA", self._img_size, FlipdotSender.C_BLACK) stream = io.BytesIO(img) image = Image.open(stream) image = image.convert(mode='RGBA') image = image.resize(self._img_size) image.save('/tmp/send2.jpeg', 'JPEG') background.paste(image, box=(0,0), mask=None) background.save('/tmp/send.jpeg', 'JPEG') self._send(background)