#!/usr/bin/env python3
import argparse
import pickle
import socketserver
import sys
from io import BytesIO
from PIL import Image
from picamera import PiCamera
class CamHandler(socketserver.BaseRequestHandler):
def handle(self):
global cam
global args
data = self.request.recv(1024)
width, height = [int(x) for x in data.decode('utf-8').split()]
if args.debug:
print("Width {} height {}".format(width, height))
stream = BytesIO()
cam.capture(stream, format='jpeg')
stream.seek(0)
picture = Image.open(stream)
ratio1 = width / height
ratio2 = picture.width / picture.height
if ratio1 < ratio2:
# Camera image is broader than desired image ratio
new_width = ratio1 * picture.height
delta = (picture.width - new_width) / 2
picture = picture.crop((delta, 0, (new_width + delta),
picture.height))
if ratio1 > ratio2:
# Camera image is taller than desired image ratio
new_height = picture.width / ratio1
delta = (picture.height - new_height) / 2
picture = picture.crop((0, delta, picture.width,
(new_height + delta)))
picture.thumbnail((width, height), Image.ANTIALIAS)
if args.debug:
print("Sending image {}".format(picture.size))
self.request.sendall(pickle.dumps(picture))
class ImageServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
def __init__ (self, server_address, handler_class=CamHandler):
socketserver.TCPServer.__init__(self, server_address, handler_class)
return
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Image server.')
parser.add_argument('--hostip', '-i', action='store', dest='address',
default='127.0.0.1', help='IP address of server host.')
parser.add_argument('--port', '-p', action='store', type=int, dest='port',
default=12345, help='Port number.')
parser.add_argument('--debug', '-d', action='store_true', default=False,
dest='debug', help='Print debugging information.')
args = parser.parse_args()
try:
cam = PiCamera()
cam.rotation = 180
time.sleep(2)
if args.debug:
print("Camera started.")
print("Server starting on {}:{}".format(args.address, args.port))
server = ImageServer((args.address, args.port),
handler_class=CamHandler)
server.serve_forever()
except Exception as e:
if args.debug:
print(e)
except KeyboardInterrupt:
pass
finally:
if args.debug:
print("Server shutting down.")
Wednesday, May 1, 2019
A second image server
Variation on the first. This server expects the client to send the dimensions of the image to be returned - if the aspect ratio is different to the camera's aspect ratio, the camera image is cropped (centrally) to the correct aspect ratio, resized using thumbnail(), and sent. Also, rather than sending a byte stream of the image data, I'm using pickle.dumps() to create a byte stream from an Image object, and sending that (since I'm already creating an Image object for the cropping and resizing).
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment