#!/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