""" Requirements Step by Step: sudo apt update sudo apt install libjpeg62-turbo-dev python3-prctl python3-picamera2 python3-libcamera libcamera-apps libcamera-dev python3 -m venv --system-site-packages env source env/bin/activate pip install flask pillow """ from flask import Flask, Response from picamera2 import Picamera2 from PIL import Image import io import base64 import serial import time import cv2 s = serial.Serial('/dev/ttyACM1', 115200, timeout=1) # serielle verbindung zum ESP aufbauen time.sleep(2) ''' Kamera Konfigurieren mit einem Format von 640x480 ''' picam2 = Picamera2() config = picam2.create_preview_configuration(main={"size": (640, 480)}) picam2.configure(config) picam2.start() MAX_RAW = 1200 MAX_B64 = 1200 # TODO: map image to MAX_B64 def encode_image_to_b64_with_limit(img: Image.Image, max_b64: int = 1024, scale_step: float = 0.9, initial_quality: int = 30, min_quality: int = 5) -> str: quality = initial_quality working_img = img.copy() while True: buf = io.BytesIO() working_img.save(buf, format="JPEG", quality=quality, optimize=True) jpeg_bytes = buf.getvalue() b64 = base64.b64encode(jpeg_bytes).decode("utf-8") if len(b64) <= max_b64 or (working_img.width < 2 or working_img.height < 2): return b64 # if len(jpeg_bytes) <= MAX_RAW: # return jpeg_bytes new_w = max(1, int(working_img.width * scale_step)) new_h = max(1, int(working_img.height * scale_step)) working_img = working_img.resize((new_w, new_h), Image.LANCZOS) if quality > min_quality: quality = max(min_quality, int(quality * scale_step)) def init_serial(): global s s = None while s is None: try: s = serial.Serial('/dev/ttyACM1', 115200, timeout=1) except Exception: time.sleep(1) continue def gen(): global s while True: arr = picam2.capture_array("main") # Einen frame holen img = Image.fromarray(arr).convert("L") # Bild in Graustufen umwandeln # TODO: skip config with 640x480 img = img.resize((640, 480), Image.LANCZOS) b64 = encode_image_to_b64_with_limit(img, MAX_B64) # Bildqualität reduzieren bis es eine Größe von maximal MAX_B64 (1200) hat print("Image_b64 size: " + str(len(b64))) try: s.write(("{\"type\":\"image\",\"data\":\"" + b64 + "\"}\n").encode("utf-8")) # Frame als JSON-String an den ESP verschicken # s.write((b64 + "\n").encode("utf-8")) except Exception: ''' War das schreiben über seriell nicht möglich wird ein erneuter Verbindungsaufbau versucht bis die Verbindung wieder steht. Es wird davon ausgegangen das wir die Verbindung verloren haben und deswegen das schreiben nicht möglich war. ''' init_serial() time.sleep(0.1) if __name__ == "__main__": # app.run(host="0.0.0.0", port=1234, threaded=True) try: gen() except KeyboardInterrupt: serial.close() print("Uebertragung beenden")