Unify JPEG capture, metadata, and saving; reducing duplication

This commit is contained in:
Julian Stirling 2025-08-22 10:24:16 +01:00
parent 4450fda945
commit 5484b51a1e
5 changed files with 83 additions and 135 deletions

View file

@ -7,14 +7,13 @@ See repository root for licensing information.
"""
from __future__ import annotations
import io
import json
import logging
from typing import Literal, Optional
from threading import Thread
import cv2
import piexif
from PIL import Image
import labthings_fastapi as lt
from labthings_fastapi.types.numpy import NDArray
@ -100,30 +99,16 @@ class OpenCVCamera(BaseCamera):
)
return frame
@lt.thing_action
def capture_jpeg(
def capture_image(
self,
metadata_getter: lt.deps.GetThingStates,
resolution: Literal["main", "full"] = "main",
stream_name: Literal["main", "full"] = "main",
wait: Optional[float] = None,
) -> JPEGBlob:
"""Acquire one image from the camera and return as a JPEG blob.
This function will produce a JPEG image.
"""
logging.warning(f"OpenCV camera doesn't respect {resolution} setting")
frame = self.capture_array()
jpeg = cv2.imencode(".jpg", frame)[1].tobytes()
exif_dict = {
"Exif": {
piexif.ExifIFD.UserComment: json.dumps(metadata_getter()).encode(
"utf-8"
)
},
"GPS": {},
"Interop": {},
"1st": {},
"thumbnail": None,
}
output = io.BytesIO()
piexif.insert(piexif.dump(exif_dict), jpeg, output)
return JPEGBlob.from_bytes(output.getvalue())
logging.warning(
f"Simulation camera doesn't respect {stream_name=} or {wait=} arguments."
)
return Image.fromarray(self.capture_array())