10.2. החזרת תמונת בזק¶
נקודת קצה של סטטוס היא בסדר, אך הסיבה שהמצלמה קיימת היא העדשה. הוסיפו נקודת קצה שמחזירה את ה-JPEG של מה שהחיישן רואה ממש עכשיו.
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'},
)
פנו אל http://<cam-ip>/snapshot.jpg מדפדפן ו-JPEG של התצוגה הנוכחית ימלא את הלשונית. רעננו ותקבלו תמונה חדשה.
10.2.1. אובייקט ה-Response¶
handler שמחזיר dict מאפשר ל-microdot לעשות את השאר. בייטים של JPEG דורשים את הצורה הארוכה: microdot.Response שנבנה במפורש. הארגומנט body מקבל כל ערך דמוי-בייטים – חוצץ image.Image של המצלמה נחשף דרך bytearray(), כך שאותו חוצץ שאליו כתב החיישן עובר ישירות אל ה-socket.
Content-Type: image/jpeg הוא מה שאומר לדפדפן להציג את הגוף כתמונה. בלעדיו הדפדפן ינסה להציג את בייטי ה-JPEG כטקסט ותראו מסך מלא ג’יבריש.
image.Image.compress() מריץ קידוד JPEG על חוצץ התמונה הקיים במקום ומחזיר את אותה תמונה (כעת בפורמט JPEG) כך שניתן לשלוח את הבייטים שלה כמות שהם. quality=85 הוא ברירת המחדל הרגילה – גבוה מספיק כדי שהתמונה תהיה חדה, נמוך מספיק כדי שהקובץ יעבור דרך קישור איטי.
10.2.2. הלכידה חוסמת את הלולאה¶
csi.CSI.snapshot() ממתין שהחיישן יסיים לחשוף ולבצע DMA של פריים לפני שהוא חוזר. בתוך handler אסינכרוני זה אומר שלולאת האירועים נעצרת למשך החשיפה – עשרה, עשרים, חמישים מילישניות תלוי בתאורה. עם לקוח אחד שמבקש route אחד בכל פעם זה בלתי נראה; עם מספר לקוחות, או קורוטינת לכידה שרצה במקביל, זה יחסום את כל השאר.
קיים וריאנט לא-חוסם של snapshot() למקרה של ריבוי קורוטינות (blocking=False מחזיר את הפריים המוכן הבא או None). עבור תמונת בזק אחת לבקשה, קריאת ברירת המחדל החוסמת היא בסדר.
הבעלים יכול כעת לפנות ל-URL ולקבל פריים חדש.