| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- from datetime import datetime
- from fastapi import APIRouter, HTTPException, Query, Response
- from app.services import (
- CameraCaptureError,
- CameraUnavailableError,
- MqttCaptureBusyError,
- MqttCaptureError,
- get_camera_service,
- get_mqtt_capture_service,
- )
- router = APIRouter(
- prefix="/camera",
- tags=["camera"],
- )
- @router.api_route("/capture", methods=["GET"], summary="拍照并直接返回图片")
- def capture_image(
- download: bool = Query(
- default=False,
- description="是否以附件下载方式返回图片。默认 False,浏览器会直接预览。",
- ),
- ) -> Response:
- """
- 拍照接口。
- 调用这个接口时,服务会即时触发树莓派相机拍照,
- 然后把最新拍到的图片直接作为 HTTP 响应返回。
- """
- camera_service = get_camera_service()
- try:
- image_bytes = camera_service.capture_jpeg()
- except (CameraUnavailableError, CameraCaptureError) as exc:
- raise HTTPException(status_code=503, detail=str(exc)) from exc
- filename = f"capture_{datetime.now().strftime('%Y%m%d_%H%M%S')}.jpg"
- disposition = "attachment" if download else "inline"
- return Response(
- content=image_bytes,
- media_type="image/jpeg",
- headers={
- "Content-Disposition": f'{disposition}; filename="{filename}"',
- "Cache-Control": "no-store",
- },
- )
- @router.api_route(
- "/capture-pair",
- methods=["GET", "POST"],
- summary="通过 MQTT 联动拍摄正反两张图片",
- )
- def capture_pair_via_mqtt() -> dict[str, object]:
- """
- 机械臂联动拍照接口。
- 调用流程:
- 1. 本接口收到请求后,临时连接 MQTT。
- 2. 发送 start 指令给机械臂。
- 3. 收到 `id=1` / `id=2` 的拍照指令后,分别覆盖保存到静态目录。
- 4. 第一张图保存后,调用识别接口获取卡牌信息。
- 5. 等待 `status=4` 作为流程结束信号。
- 6. 上传两张图到 MinIO,并返回 MinIO URL 和识别结果。
- """
- mqtt_capture_service = get_mqtt_capture_service()
- try:
- result = mqtt_capture_service.capture_pair()
- except MqttCaptureBusyError as exc:
- raise HTTPException(status_code=409, detail=str(exc)) from exc
- except MqttCaptureError as exc:
- raise HTTPException(status_code=503, detail=str(exc)) from exc
- return result
|