10.2. Vrácení snímku

Stavový koncový bod je fajn, ale důvodem existence kamery je objektiv. Přidejte koncový bod, který vrátí JPEG toho, na co se senzor právě dívá.

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'},
    )

Otevřete v prohlížeči http://<cam-ip>/snapshot.jpg a kartu zaplní JPEG aktuálního pohledu. Obnovte stránku a dostanete čerstvý.

10.2.1. Objekt Response

Handler vracející slovník nechá zbytek na microdotu. Bajty JPEG vyžadují dlouhou formu: explicitně sestavený microdot.Response. Argument body přijímá libovolnou hodnotu podobnou bajtům – buffer image.Image kamery je vystaven přes bytearray(), takže tentýž buffer, do kterého senzor zapsal, jde rovnou do socketu.

Content-Type: image/jpeg je to, co řekne prohlížeči, aby tělo vykreslil jako obraz. Bez něj by se prohlížeč pokusil zobrazit bajty JPEG jako text a uviděli byste obrazovku plnou nesmyslů.

image.Image.compress() provede kódování JPEG na stávajícím obrazovém bufferu na místě a vrátí tentýž obraz (nyní ve formátu JPEG), takže jeho bajty lze odeslat tak, jak jsou. quality=85 je obvyklá výchozí hodnota – dostatečně vysoká, aby byl obraz ostrý, a dostatečně nízká, aby se soubor vešel přes pomalé připojení.

10.2.2. Pořízení snímku blokuje smyčku

csi.CSI.snapshot() čeká, než senzor dokončí expozici a přenos snímku přes DMA, teprve poté se vrátí. Uvnitř asynchronního handleru to znamená, že se smyčka událostí zastaví po dobu trvání expozice – deset, dvacet, padesát milisekund podle osvětlení. S jedním klientem, který se ptá na jednu cestu naráz, je to neviditelné; s více klienty nebo s koroutinou pro pořizování snímků běžící souběžně by to zablokovalo vše ostatní.

Pro případ více koroutin existuje neblokující varianta snapshot() (blocking=False vrátí další připravený snímek nebo None). Pro jeden snímek na požadavek je výchozí blokující volání v pořádku.

Vlastník nyní může kliknout na URL a dostat čerstvý snímek.