10.2. Trả về một ảnh chụp

Một endpoint trạng thái thì ổn, nhưng lý do camera tồn tại là ống kính. Thêm một endpoint trả về JPEG của những gì cảm biến đang nhìn vào ngay lúc này.

import csi
from microdot import Response

csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QVGA)

@app.get('/snapshot.jpg')
async def snapshot(request):
    img = csi0.snapshot().compress(quality=85)
    return Response(
        body=img.bytearray(),
        headers={'Content-Type': 'image/jpeg'},
    )

Truy cập http://<cam-ip>/snapshot.jpg từ trình duyệt và một JPEG của chế độ xem hiện tại sẽ lấp đầy tab. Làm mới và bạn sẽ nhận được một ảnh mới.

10.2.1. Đối tượng Response

Một handler trả về dict để microdot làm phần còn lại. Các byte JPEG cần dạng đầy đủ: một microdot.Response được xây dựng tường minh. Tham số body nhận bất kỳ giá trị dạng bytes nào -- bộ đệm khung hình image.Image của camera được hiển thị qua bytearray(), vì vậy cùng một bộ đệm mà cảm biến đã ghi vào có thể được gửi thẳng đến socket.

Content-Type: image/jpeg là thứ cho trình duyệt biết cần render phần body là ảnh. Nếu không có nó, trình duyệt sẽ cố gắng hiển thị các byte JPEG dưới dạng văn bản và bạn sẽ thấy một màn hình đầy ký tự rác.

image.Image.compress() chạy mã hóa JPEG trên bộ đệm ảnh hiện có tại chỗ và trả về cùng ảnh đó (hiện ở định dạng JPEG) để có thể gửi các byte của nó nguyên trạng. quality=85 là giá trị mặc định thông thường -- đủ cao để ảnh sắc nét, đủ thấp để tệp có thể truyền qua kết nối chậm.

10.2.2. Capture chặn vòng lặp

csi.CSI.snapshot() chờ cảm biến hoàn thành việc phơi sáng và DMA'ing một khung hình trước khi trả về. Bên trong một async handler, điều này có nghĩa là vòng lặp sự kiện bị đình trệ trong thời gian phơi sáng -- mười, hai mươi, năm mươi mili giây tùy thuộc vào ánh sáng. Với một client yêu cầu một route tại một thời điểm thì điều này vô hình; với nhiều client, hoặc một coroutine capture chạy song song, nó sẽ chặn mọi thứ khác.

Một biến thể không chặn của snapshot() tồn tại cho trường hợp nhiều coroutine (blocking=False trả về khung hình sẵn sàng tiếp theo hoặc None). Đối với một ảnh chụp mỗi yêu cầu, lệnh gọi chặn mặc định là ổn.

Chủ sở hữu giờ có thể truy cập một URL và nhận được một khung hình mới.