Camera
Group: Capture
Description
A Camera lets the visitor take a photo with their webcam and
submit it with the form. It shows an "Enable camera" button; once
the visitor grants permission, a live preview appears with a "Take
photo" button. The captured photo is submitted under the
component's name, and the receiving route chooses what to get: a
Photo (the full record, including whether permission was
granted) or a Picture (just the
image, ready to display or edit).
Syntax
Camera(name)
Parameters
| Parameter | Type | Default | Meaning |
|---|---|---|---|
name |
str |
required | The field's name, matching a parameter of the receiving route. |
width |
int |
640 |
Requested preview and photo width, in pixels. |
height |
int |
480 |
Requested preview and photo height, in pixels. |
facing |
str |
"user" |
Which camera to prefer on phones: "user" (front, selfie) or "environment" (rear). |
mirror |
bool |
True |
Mirror the live preview like a selfie mirror. The captured photo is never mirrored. |
show |
bool |
True |
Display the camera UI. |
on_capture |
str |
none | Route to call when a photo is taken. |
on_denied |
str |
none | Route to call when the visitor refuses permission. |
on_error |
str |
none | Route to call when the camera fails. |
Examples
With a Photo annotation, the route receives the full record and
can check whether a photo actually exists before showing it. The
picture property is the image as a Picture, or None when
nothing was captured:
from drafter import *
from dataclasses import dataclass
@dataclass
class State:
pass
@route
def index(state: State) -> Page:
return Page(state, [
Header("Pet Portrait Studio"),
"Hold your pet up to the camera!\n",
Camera("shot"),
"\n",
Button("Save portrait", "portrait")
])
@route
def portrait(state: State, shot: Photo) -> Page:
if shot.picture is None:
return Page(state, [
"No photo yet (" + shot.status + "). Go back and "
"take one!\n",
Button("Back", "index")
])
return Page(state, [
Header("A masterpiece"),
Image(shot.picture),
"\n",
Button("Take another", "index")
])
start_server(State())
With a Picture annotation, the route gets the image directly and
can use every Picture transformation:
from drafter import *
from dataclasses import dataclass
@dataclass
class State:
pass
@route
def index(state: State) -> Page:
return Page(state, [
Header("Photo Booth"),
Camera("snapshot", facing="user"),
"\n",
Button("Develop", "develop")
])
@route
def develop(state: State, snapshot: Picture) -> Page:
return Page(state, [
Header("Your prints"),
Image(snapshot.grayscale()),
Image(snapshot.flip_horizontal()),
"\n",
Button("New photo", "index")
])
start_server(State())
Notes
- A
Photocarriesstatus, an optionalmessage, the photo'swidthandheight, and thepictureproperty. Thestatusis"granted"once a photo has been taken,"denied"when permission was refused, and"prompt","pending","live","error", or"unavailable"along the way. - The
Pictureannotation is the convenient path, but if the visitor never took a photo, the route stops with a friendly error. Use thePhotoannotation when you want to handle that case yourself, as the first example does. - After a photo is taken, the camera stream stops (and the camera light turns off); "Retake" starts it again.
- Store a captured
Picturein state to keep it across pages, and hand it to Download to let the visitor save it. - Ask for the camera only when your app really uses it, and make it obvious what happens to the photos. In a Drafter app they stay on the visitor's own computer unless your code offers them for download.
Related components
- Image: display the captured photo.
- FileUpload: receive an existing image file instead of taking a new one.