...
 
Commits (3)
......@@ -13,6 +13,9 @@ display image:
draw over previous image:
`curl -XPOST http://host/update --data @file.svg` or `curl -XPOST http://host/update --data-binary @file.jpg`
show video:
`curl -XPOST http://host/video --data 'url=http://video/file'`
display color:
`curl -XPOST http://host/fill --data 'r=255&g=1&b=0&a=255'`
......
......@@ -6,7 +6,7 @@ After=multi-user.target
Type=simple
ExecStartPre=/bin/dmesg -D
ExecStartPre=/bin/bash -c '/bin/echo 0 > /sys/class/graphics/fbcon/cursor_blink'
ExecStart=/opt/imageshow/server.py 80 1
ExecStart=/usr/bin/python3 -u /opt/imageshow/server.py 80 0
ExecStop=/bin/dmesg -E
ExecStop=/bin/bash -c '/bin/echo 1 > /sys/class/graphics/fbcon/cursor_blink'
Restart=always
......
......@@ -22,7 +22,8 @@ RSVGCONVERT_ARGS = ['--unlimited', '--keep-image-data', '--background-color=None
BLANKINGCMD = '/usr/bin/vcgencmd'
BLANKINGARGS_OFF = ['display_power', '0']
BLANKINGARGS_ON = ['display_power', '1']
ROTATION = 0
VIDEOCMD = '/usr/bin/omxplayer.bin'
VIDEOARGS = ['--no-osd', '--aspect-mode', 'fill', '--orientation', '270']
class Server(BaseHTTPRequestHandler):
_processing = False
......@@ -31,7 +32,8 @@ class Server(BaseHTTPRequestHandler):
self._respondCurrentImage()
def do_POST(self):
self._payloadLength = int(self.headers['Content-Length'])
contentLength = self.headers['Content-Length']
self._payloadLength = int(contentLength) if contentLength else 0
if self.path == '/' or self.path == '/update':
self._processImage()
elif self.path == '/off':
......@@ -40,6 +42,8 @@ class Server(BaseHTTPRequestHandler):
self._setDisplayPower(True)
elif self.path == '/fill':
self._fillDisplay()
elif self.path == '/video':
self._showVideo()
else:
self._sendResponse(404, b'Not Found')
......@@ -51,7 +55,7 @@ class Server(BaseHTTPRequestHandler):
def _respondCurrentImage(self):
fh = open('/dev/' + FRAMEBUFFER, 'rb')
image = Image.frombytes('RGBA', (buf_width, buf_height), fh.read(), 'raw').convert('RGBA').rotate(ROTATION * -90, expand=1)
image = Image.frombytes('RGBA', (buf_width, buf_height), fh.read(), 'raw').convert('RGBA').rotate(rotation * -90, expand=1)
fh.close()
b,g,r,a = image.split()
new_image = Image.merge("RGBA", (r,g,b,a))
......@@ -84,10 +88,18 @@ class Server(BaseHTTPRequestHandler):
self._processing = False
self._sendResponse(200, b'OK')
def _showVideo(self):
global videoprocess
setDisplayPower(True)
stopVideo()
postvars = parse_qs(self.rfile.read(self._payloadLength))
if b'url' in postvars:
args = [VIDEOCMD] + VIDEOARGS + [postvars[b'url'][0]]
videoprocess = Popen(args, stdout=PIPE, stdin=PIPE, stderr=PIPE)
self._sendResponse(200, b'OK')
def _fillDisplay(self):
self._setDisplayPower(True)
setDisplayPower(True)
postvars = parse_qs(self.rfile.read(self._payloadLength))
print(postvars)
buffer = bytearray()
buffer.extend(struct.pack('B', int(postvars[b'b'][0])))
buffer.extend(struct.pack('B', int(postvars[b'g'][0])))
......@@ -97,6 +109,7 @@ class Server(BaseHTTPRequestHandler):
with open('/dev/' + FRAMEBUFFER, 'wb') as f:
f.write(buffer)
stopVideo()
self._sendResponse(200, b'OK')
def _setDisplayPower(self, turnOn):
if self._payloadLength:
......@@ -111,6 +124,8 @@ class Server(BaseHTTPRequestHandler):
buf_width = 0
buf_height = 0
lastImage = None
videoprocess = False
rotation = 0
def process(payload, isUpdate, isSvg):
global lastImage
......@@ -147,7 +162,7 @@ def render(payload, isSvg):
else:
print('detected non-SVG')
imageData = payload
return Image.open(BytesIO(imageData)).convert('RGBA').rotate(ROTATION * 90, expand=1)
return Image.open(BytesIO(imageData)).convert('RGBA').rotate(rotation * 90, expand=1)
def convert(image):
print('converting')
......@@ -159,6 +174,7 @@ def writeToFramebuffer(image):
setDisplayPower(True)
with open('/dev/' + FRAMEBUFFER, 'wb') as f:
f.write(image.tobytes())
stopVideo()
def setDisplayPower(turnOn):
args = [BLANKINGCMD]
......@@ -167,9 +183,17 @@ def setDisplayPower(turnOn):
else:
args += BLANKINGARGS_OFF
Popen(args, stdout=PIPE, stdin=PIPE, stderr=PIPE)
def stopVideo():
global videoprocess
if videoprocess:
print('stopping video')
videoprocess.communicate(input=b'q')
videoprocess.kill()
videoprocess = None
def init():
if(ROTATION % 2 == 0):
if(rotation % 2 == 0):
initfile = '%dX%d.svg' % (buf_width, buf_height)
else:
initfile = '%dX%d.svg' % (buf_height, buf_width)
......@@ -186,7 +210,7 @@ def run(server_class=HTTPServer, handler_class=Server, port=80):
w, h = fbsize.read().strip().split(',')
buf_width = int(w)
buf_height = int(h)
lastImage = Image.new('RGBA', (buf_width, buf_height)).rotate(ROTATION * 90, expand=1)
lastImage = Image.new('RGBA', (buf_width, buf_height)).rotate(rotation * 90, expand=1)
print('detected frame buffer size %dX%d' % (buf_width, buf_height))
chdir(path.dirname(path.realpath(__file__)))
......@@ -204,7 +228,7 @@ if __name__ == "__main__":
atexit.register(shutdown)
try:
if len(sys.argv) == 3:
ROTATION = int(sys.argv[2])
rotation = int(sys.argv[2])
if len(sys.argv) >= 2:
run(port=int(sys.argv[1]))
else:
......