forked from w3c/mediacapture-image
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
524 lines (486 loc) · 31.8 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' lang='en'>
<head>
<meta charset='utf-8'/>
<title>Mediastream Image Capture</title>
<script class='remove'>
var respecConfig = {
specStatus: "ED"
, shortName: "image-capture"
, editors: [
{ name: "Giridhar Mandyam"
, company: "Qualcomm Innovation Center, Inc"
, companyURL: "http://www.qualcomm.com/about/businesses/quicinc" }
]
, edDraftURI: "http://gmandyam.github.com/image-capture"
, previousURI: "http://gmandyam.github.com/image-capture"
, copyrightStart: 2012
, noIDLIn: true
, wg: ["Web Real-Time Communication Working Group", "Device APIs Working Group"]
, wgURI: ["http://www.w3.org/2011/04/webrtc/","http://www.w3.org/2009/dap"]
, wgPublicList: "public-media-capture"
, wgPatentURI: "XXX"
, isRecTrack: false
, isNoTrack: true
, format: 'markdown'
};
</script>
<script src='https://www.w3.org/Tools/respec/respec-w3c-common.js' class='remove' async></script>
</head>
<body>
<section id='sotd'>
Comments on this document are welcomed.
</section>
<section id='abstract'>
This document specific the takePhoto() and grabFrame() methods, and corresponding camera settings for use with MediaStreams as defined in Media Capture and Streams [[!GETUSERMEDIA]].
</section>
Introduction
------------
<p>The API defined in this document taks a valid MediaStream and returns an encoded image in the form of a <code>Blob</code> (as defined in [[!FILE-API]]). The image is
provided by the capture device that provides the MediaStream. Moreover,
picture-specific settings can be optionally provided as arguments that can be applied to the image being captured.</p>
Image Capture API
--------------
<dl title='[Constructor(VideoStreamTrack track)] interface ImageCapture : EventTarget' class='idl'>
<dd>interface ImageCapture: EventTarget</dd>
<dt>readonly attribute PhotoOptions photoOptions</dt>
<dd>Describes current photo settings</dd>
<dt>readonly attribute VideoStreamTrack videoStreamTrack</dt>
<dd>The MediaStreamTrack passed into the constructor</dd>
<dt>readonly attribute MediaStream previewStream</dt>
<dd>The MediaStream that provides a camera preview</dd>
<dt>attribute EventHandler onphoto</dt>
<dd>Register/unregister for photo events of type <code>BlobEvent</code>. The handler should expect to get a <code>BlobEvent</code> object as its first parameter.</dd>
<dt>attribute EventHandler onerror</dt>
<dd>Register/unregister for Image Capture error events of type <code>ImageCaptureErrorEvent</code>. The handler should expect to get an <code>ImageCaptureError</code> object as its first parameter.</dd>
<dt>attribute EventHandler onoptions</dt>
<dd>Register/unregister for photo settings change events of type <code>SettingsChangeEvent</code>.</dd>
<dt>attribute EventHandler onframe</dt>
<dd>Register/unregister for frame capture events of type <code>FrameGrabEvent</code>. The handler should expect to get a <code>FrameGrabEvent</code> object as its first parameter.</dd>
<dt>void setOptions(PhotoSettings? photoSettings)</dt>
<dd>When the <code>setOptions()</code> method of an <code>ImageCapture</code> object is invoked, then a valid <code>PhotoSettings</code> object <em title="must" class="rfc2119">must</em> be passed in the method to the
<code>ImageCapture</code> object. If the UA can successfully apply the settings, then the UA <em title="must" class="rfc2119">must</em> fire a <code>SettingsChangeEvent</code> event at the
<code>onoptions</code> event handler (if specified). If the UA cannot successfully apply the settings, then the UA
<em title="must" class="rfc2119">must</em> fire an <code>ImageCaptureErrorEvent</code> at the <code>ImageCapture</code> object whose <code>code</code> is set to OPTIONS_ERROR. </dd>
<dt>void takePhoto ()</dt>
<dd>When the <code>takePhoto()</code> method of an <code>ImageCapture</code> object is invoked,
then if the <code>readyState</code> of the <code>VideoStreamTrack</code> provided in the constructor is not "live", the UA <em title="must" class="rfc2119">must</em> fire an <code>ImageCaptureErrorEvent</code> event at the <code>ImageCapture</code> object with a
new <code>ImageCaptureError</code> object whose <code>code</code> is set to INVALID_TRACK. If the UA is unable to execute the <code>takePhoto()</code> method for any
other reason (for example, upon invocation of multiple takePhoto() method calls in rapid succession), then the UA <em title="must" class="rfc2119">must</em> fire an <code>ImageCaptureErrorEvent</code> event at the <code>ImageCapture</code> object with a
new <code>ImageCaptureError</code> object whose <code>code</code> is set to PHOTO_ERROR.
Otherwise it <em title="must" class="rfc2119">must</em>
queue a task, using the DOM manipulation task source, that runs the following steps:
<ol>
<li>Gather data from the <code>VideoStreamTrack</code> into a <code>Blob</code> containing a single still image. The method of doing
this will depend on the underlying device. Devices
may temporarily stop streaming data, reconfigure themselves with the appropriate photo settings, take the photo,
and then resume streaming. In this case, the stopping and restarting of streaming <em title="should" class="rfc2119">should</em>
cause <code>mute</code> and <code>unmute</code> events to fire on the Track in question. </li>
<li>Raise a <code>BlobEvent</code> event containing the <code>Blob</code> to the <code>onphoto</code> event handler (if specified).</li></dd>
<dt>void grabFrame()</dt>
<dd>When the <code>grabFrame()</code> method of an <code>ImageCapture</code> object is invoked, then if the <code>readyState</code> of the <code>VideoStreamTrack</code> provided in the contructor is not "live", the UA <em title="must" class="rfc2119">must</em> fire an <code>ImageCaptureErrorEvent</code> event at the <code>ImageCapture</code> object with a
new <code>ImageCaptureError</code> object whose <code>code</code> is set to INVALID_TRACK. If the UA is unable to execute the <code>grabFrame()</code> method for any
other reason, then the UA <em title="must" class="rfc2119">must</em> fire an <code>ImageCaptureErrorEvent</code> event at the <code>ImageCapture</code> object with a
new <code>ImageCaptureError</code> object whose <code>code</code> is set to FRAME_ERROR. Otherwise it <em title="must" class="rfc2119">must</em>
queue a task, using the DOM manipulation task source, that runs the following steps:
<ol>
<li>Gather data from the <code>VideoStreamTrack</code> into an <code>ImageData</code> object (as defined in [[!CANVAS-2D]]) containing a single still frame in RGBA format. The <code>width</code> and <code>height</code> of the
<code>ImageData</code> object are derived from the constraints of the <code>VideoStreamTrack</code>. </li>
<li>Raise a <code>FrameGrabEvent</code> event containing the <code>ImageData</code> to the <code>onframe</code> event handler (if specified). {Note: <code>grabFrame()</code> returns data only once upon being invoked.}</li>
</dd>
</dl>
<code>FrameGrabEvent</code>
--------------
<dl title='[Constructor(DOMString type, optional FrameGrabEventInit frameGrabInitDict)] interface FrameGrabEvent : Event' class='idl'>
<dt>readonly attribute ImageData imageData</dt>
<dd>Returns an <code>ImageData</code> object whose <code>width</code> and <code>height</code> attributes indicates the dimensions of the captured frame. </dd>
</dl>
##### <code>FrameGrabEventInit</code> Dictionary
<dl title='dictionary FrameGrabEventInit : EventInit' class='idl'>
<dt>ImageData imageData</dt>
<dd>An <code>ImageData</code> object containing the data to deliver via this event.</dd>
</dl>
<code>ImageCaptureErrorEvent</code>
--------------
<dl title='[Constructor(DOMString type, optional ImageCaptureErrorEventInit imageCaptureErrorInitDict)] interface ImageCaptureErrorEvent : Event' class='idl'>
<dt>readonly attribute ImageCaptureError imageCaptureError</dt>
<dd>Returns an <code>ImageCaptureError</code> object whose <code>code</code> attribute indicates the type of error occurrence. </dd>
</dl>
##### <code>ImageCaptureErrorEventInit</code> Dictionary
<dl title='dictionary ImageCaptureErrorEventInit : EventInit' class='idl'>
<dt>ImageCaptureError imageCaptureError</dt>
<dd>an <code>ImageCaptureError</code> object containing the data to deliver via this event.</dd>
</dl>
<code>BlobEvent</code>
--------------
<dl title='[Constructor(DOMString type, optional BlobEventInit blobInitDict)] interface BlobEvent : Event' class='idl'>
<dt>readonly attribute Blob data</dt>
<dd>Returns a <code>Blob</code> object whose type attribute indicates the encoding of the blob data. An implementation must return a Blob in a format that is capable of being viewed in an HTML <code><img></code> tag. </dd>
</dl>
##### <code>BlobEventInit</code> Dictionary
<dl title='dictionary BlobEventInit : EventInit' class='idl'>
<dt>Blob data</dt>
<dd>A <code>Blob</code> object containing the data to deliver via this event.</dd>
</dl>
<code>SettingsChangeEvent</code>
--------------
<dl title='[Constructor(DOMString type, optional SettingsChangeEventInit photoSettingsInitDict)] interface PhotoSettingsEvent : Event' class='idl'>
<dt>readonly attribute PhotoSettings photoSettings</dt>
<dd>Returns a <code>PhotoSettings</code> object whose type attribute indicates the current photo settings. </dd>
</dl>
##### <code>SettingsChangeEventInit</code> Dictionary
<dl title='dictionary SettingsChangeEventInit : EventInit' class='idl'>
<dt>PhotoSettings photoSettings</dt>
<dd>A <code>PhotoSettings</code> object containing the data to deliver via this event.</dd>
</dl>
<code>ImageCaptureError</code>
-----------------
<p>The <code>ImageCaptureError</code> object is passed to an <code>onerror</code> event handler of an
<code>ImageCapture</code> object if an error occurred when the object was created or any of its methods were invoked.</p>
<dl title='[NoInterfaceObject] interface ImageCaptureError' class='idl'>
<dt>const unsigned short FRAME_ERROR=1</dt>
<dd>An <code>ImageCaptureError</code> object must set its <code>code</code> value to this constant if an error occurred upon invocation of the <code>grabFrame()</code> method of the <code>ImageCapture</code> interface.</dd>
<dt>const unsigned short OPTIONS_ERROR=2</dt>
<dd>An <code>ImageCaptureError</code> object must set its <code>code</code> value to this constant if an error occurred upon invocation of the <code>setOptions()</code> method of the <code>ImageCapture</code> interface.</dd>
<dt>const unsigned short PHOTO_ERROR=3</dt>
<dd>An <code>ImageCaptureError</code> object must set its <code>code</code> value to this constant if an error occurred upon invocation of the <code>takePhoto()</code> method of the <code>ImageCapture</code> interface.</dd>
<dt>const unsigned short ERROR_UNKNOWN=4</dt>
<dd>An <code>ImageCaptureError</code> object must set its <code>code</code> value to this constant if an error occurred due to indeterminate cause upon invocation of any method of the <code>ImageCapture</code> interface.</dd>
<dt>readonly attribute unsigned short code</dt>
<dd>The <code>code</code> attribute returns the appropriate code for the error event, derived from the constants defined in the <code>ImageCaptureError</code> interface.</dd>
<dt>readonly attribute DOMString message</dt>
<dd>The <code>message</code> attribute must return an error message describing the details of the error encountered.</dd>
</dl>
<section>
<h2><code>MediaSettingsRange</code></h2>
<dl title='interface MediaSettingsRange' class='idl'>
<dt>readonly attribute unsigned long max</dt>
<dd>The maximum value of this setting</dd>
<dt>readonly attribute unsigned long min</dt>
<dd>The minimum value of this setting</dd>
<dt>readonly attribute unsigned long initial</dt>
<dd>The current value of this setting</dd>
</dl>
</section>
<section>
<h2><code>MediaSettingsItem</code></h2>
<p>The <code>MediaSettingsItem</code> interface is now defined, which allows for a single setting to be managed.</p>
<dl title='interface MediaSettingsItem' class='idl'>
<dt>readonly attribute any value</dt>
<dd>Value of current setting.</dd>
</dl>
<p></p>
</section>
<section>
<h2><code>PhotoOptions</code></h2>
<p>The PhotoOptions attribute of the <code>ImageCapture</code> object provides
the photo-specific settings options and current settings values. The following definitions are assumed
for individual settings and are provided for information purposes:</p>
<ol>
<li><i>White balance mode</i> is a setting that cameras use to adjust for different color temperatures. Color temperature is
the temperature of background light (measured in Kelvin normally). This setting can also be automatically
determined by the implementation. If 'automatic' mode is selected, then the Kelvin setting for White Balance Mode
may be overridden. Typical temprature ranges for different modes are provided below:
<table border="1">
<tr>
<th>Mode</th>
<th>Kelvin range</th>
</tr>
<tr>
<td>incandescent</td>
<td>2500-3500</td>
</tr>
<tr>
<td>fluorescent</td>
<td>4000-5000</td>
</tr>
<tr>
<td>warm-fluorescent</td>
<td>5000-5500</td>
</tr>
<tr>
<td>daylight</td>
<td>5500-6500</td>
</tr>
<tr>
<td>cloudy-daylight</td>
<td>6500-8000</td>
</tr>
<tr>
<td>twilight</td>
<td>8000-9000</td>
</tr>
<tr>
<td>shade</td>
<td>9000-10000</td>
</tr>
</table>
</li>
<li><i>Exposure</i> is the amount of light allowed to fall on the photographic medium. Auto-exposure mode is a camera setting
where the exposure levels are automatically adjusted by the implementation based on the subject of the photo.</li>
<li><i>Exposure Compensation</i> is a numeric camera setting that adjusts the exposure level from the current value used by the implementation. This value can
be used to bias the exposure level enabled by auto-exposure.</li>
<li>The <i>ISO</i> setting of a camera describes the sensistivity of the camera to light. It is a numeric value, where the lower the value
the greater the sensitivity. This setting in most implementations relates to shutter speed, and is sometimes known as the ASA setting.</li>
<li><i>Red Eye Reduction</i> is a feature in cameras that is designed to limit or prevent the appearance of
red pupils ("Red Eye") in photography subjects due prolonged exposure to a camera's flash.</li>
<li><i>Brightness</i> refers to the numeric camera setting that adjusts the perceived amount of light emitting from the photo object. A higher brightness setting increases the intensity of darker areas in a scene while compressing the intensity of brighter parts of the scene.</li>
<li><i>Contrast</i> is the numeric camera setting that controls the difference in brightness between light and dark areas in a scene. A higher contrast setting reflects an expansion in the difference in brightness.</li>
<li><i>Saturation</i> is a numeric camera setting that controls the intensity of color in a scene (i.e. the amount of gray in the scene). Very low saturation levels will result in photo's closer to black-and-white.</li>
<li><i>Sharpness</i> is a numeric camera setting that controls the intensity of edges in a scene. Higher sharpness settings result in higher edge intensity, while lower settings result in less contrast and blurrier edges (i.e. soft focus).</li>
<li><i>Zoom</i> is a numeric camera setting that controls the focal length of the lens. The setting usually represents a ratio, e.g. 4 is a zoom ratio of 4:1. The minimum value is usually 1, to represent a 1:1 ratio (i.e. no zoom).</li>
</ol>
<dl title='interface PhotoOptions' class='idl'>
<dt>attribute MediaSettingsItem autoWhiteBalanceMode</dt>
<dd>This reflects whether automated White Balance Mode selection is on or off, and is boolean - on is true</dd>
<dt>attribute MediaSettingsRange whiteBalanceMode</dt>
<dd>This reflects the current white balance mode setting. Values are of type <code>WhiteBalanceModeEnum</code>.</dd>
<dt>attribute ExposureMode autoExposureMode</dt>
<dd>This reflects the current auto exposure mode setting. Values are of type <code>ExposureMode</code>.</dd>
<dt>attribute MediaSettingsRange exposureCompensation</dt>
<dd>This reflects the current exposure compensation setting and permitted range. Values are numeric.</dd>
<dt>attribute MediaSettingsRange iso</dt>
<dd>This reflects the current camera ISO setting and permitted range. Values are numeric.</dd>
<dd>This feature reflects the current exposure level for recorded images. Values are numeric.</dd>
<dt>attribute MediaSettingsItem redEyeReduction</dt>
<dd>This reflects whether camera red eye reduction is on or off, and is boolean - on is true</dd>
<dt>attribute MediaSettingsRange brightness</dt>
<dd>This reflects the current brightness setting of the camera and permitted range. Values are numeric.</dd>
<dt>attribute MediaSettingsRange constrast</dt>
<dd>This reflects the current contrast setting of the camera and permitted range. Values are numeric.</dd>
<dt>attribute MediaSettingsRange saturation</dt>
<dd>This reflects the current saturation setting of the camera and permitted range. Values are numeric.</dd>
<dt>attribute MediaSettingsRange sharpness</dt>
<dd>This reflects the current sharpness setting of the camera and permitted range. Values are numeric.</dd>
<dt>attribute MediaSettingsRange imageHeight</dt>
<dd>This reflects the image height range supported by the UA and the current height setting.</dd>
<dt>attribute MediaSettingsRange imageWidth</dt>
<dd>This reflects the image width range supported by the UA and the current width setting.</dd>
<dt>attribute MediaSettingsRange zoom</dt>
<dd>This reflects the zoom value range supported by the UA and the current zoom setting.</dd>
</dl>
<p></p>
</section>
<section>
<h2><code>ExposureMode</code></h2>
<dl title='enum ExposureModeEnum' class='idl'>
<dt>frame-average</dt>
<dd>Average of light information from entire scene</dd>
<dt>center-weighted</dt>
<dd>Sensitivity concentrated towards center of viewfinder</dd>
<dt>spot-metering</dt>
<dd>Spot-centered weighting</dd>
</dl>
</section>
<section>
<h2><code>PhotoSettings</code></h2>
<p>The <code>PhotoSettings</code> object is optionally passed into the <code>ImageCapture.setOptions()</code> method
in order to modify capture device settings specific to still imagery. Each of the attributes in this object
are optional.</p>
<dl title='dictionary PhotoSettings' class='idl'>
<dt>attribute boolean autoWhiteBalanceMode</dt>
<dd>This reflects whether automatic White Balance Mode selection is desired.</dd>
<dt>attribute unsigned long whiteBalanceMode</dt>
<dd>This reflects the desired white balance mode setting.</dd>
<dt>attribute any autoExposureMode</dt>
<dd>This reflects the desired auto exposure mode setting. Acceptable values are of type <code>ExposureModeEnum</code>.</dd>
<dt>attribute unsigned long exposureCompensation</dt>
<dd>This reflects the desired exposure compensation setting.</dd>
<dt>attribute unsigned long iso</dt>
<dd>This reflects the desired camera ISO setting.</dd>
<dd>This feature reflects the current exposure level for recorded images. Values are numeric.</dd>
<dt>attribute boolean redEyeReduction</dt>
<dd>This reflects whether camera red eye reduction is desired</dd>
<dt>attribute unsigned long brightness</dt>
<dd>This reflects the desired brightness setting of the camera.</dd>
<dt>attribute unsigned long constrast</dt>
<dd>This reflects the desired contrast setting of the camera.</dd>
<dt>attribute unsigned long saturation</dt>
<dd>This reflects the desired saturation setting of the camera.</dd>
<dt>attribute unsigned long sharpness</dt>
<dd>This reflects the desired sharpness setting of the camera.</dd>
<dt>attribute unsigned long imageHeight</dt>
<dd>This reflects the desired image height. The UA <em title="must" class="rfc2119">must</em> select the closest height value this setting if it supports a discrete set of height options. </dd>
<dt>attribute unsigned long imageWidth</dt>
<dd>This reflects the desired image width. The UA <em title="must" class="rfc2119">must</em> select the closest width value this setting if it supports a discrete set of width options.</dd>
</dl>
</section>
<section>
<h2>Promise Extensions to <code>ImageCapture</code></h2>
<p>If the User Agent supports <i>Promises</i>, then the following may be used. Any <i>Promise</i> object is assumed to have <i>resolver</i> object, with <i>resolve()</i> and <i>reject()</i> methods associated with it.
{NOTE: The <code>setOptions()</code> method is not recast as a <i>Promise</i> due to the possibility that its associated event handler <code>onoptions</code> may be repeatedly invoked.}</p>
<dl title='[Constructor(VideoStreamTrack track)] interface ImageCapture : EventTarget' class='idl'>
<dd>interface ImageCapture: EventTarget</dd>
<dt>readonly attribute PhotoOptions photoOptions</dt>
<dd>Describes current photo settings</dd>
<dt>readonly attribute VideoStreamTrack videoStreamTrack</dt>
<dd>The MediaStreamTrack passed into the constructor</dd>
<dt>readonly attribute MediaStream previewStream</dt>
<dd>The MediaStream that provides a camera preview</dd>
<dt>attribute EventHandler onerror</dt>
<dd>Register/unregister for Image Capture error events of type <code>ImageCaptureErrorEvent</code>. The handler should expect to get an <code>ImageCaptureError</code> object as its first parameter.</dd>
<dt>attribute EventHandler onoptions</dt>
<dd>Register/unregister for photo settings change events of type <code>SettingsChangeEvent</code>.</dd>
<dt>void setOptions(PhotoSettings? photoSettings)</dt>
<dd>When the <code>setOptions()</code> method of an <code>ImageCapture</code> object is invoked, then a valid <code>PhotoSettings</code> object <em title="must" class="rfc2119">must</em> be passed in the method to the
<code>ImageCapture</code> object. If the UA can successfully apply the settings, then the UA <em title="must" class="rfc2119">must</em> fire a <code>SettingsChangeEvent</code> event at the
<code>onoptions</code> event handler (if specified). If the UA cannot successfully apply the settings, then the UA
<em title="must" class="rfc2119">must</em> fire an <code>ImageCaptureErrorEvent</code> at the <code>ImageCapture</code> object whose <code>code</code> is set to OPTIONS_ERROR. </dd>
<dt>Promise takePhoto ()</dt>
<dd>When the <code>takePhoto()</code> method of an <code>ImageCapture</code> object is invoked, a new <i>Promise</i> object is returned.
If the <code>readyState</code> of the <code>VideoStreamTrack</code> provided in the constructor is not "live", the UA <em title="must" class="rfc2119">must</em> return an <code>ImageCaptureErrorEvent</code> event to the <i>resolver</i> object's <i>reject()</i> method with a
new <code>ImageCaptureError</code> object whose <code>code</code> is set to INVALID_TRACK. If the UA is unable to execute the <code>takePhoto()</code> method for any
other reason (for example, upon invocation of multiple takePhoto() method calls in rapid succession), then the UA <em title="must" class="rfc2119">must</em> return an <code>ImageCaptureErrorEvent</code> event to the <i>resolver</i> object's <i>reject()</i> method with a
new <code>ImageCaptureError</code> object whose <code>code</code> is set to PHOTO_ERROR.
Otherwise it <em title="must" class="rfc2119">must</em>
queue a task, using the DOM manipulation task source, that runs the following steps:
<ol>
<li>Gather data from the <code>VideoStreamTrack</code> into a <code>Blob</code> containing a single still image. The method of doing
this will depend on the underlying device. Devices
may temporarily stop streaming data, reconfigure themselves with the appropriate photo settings, take the photo,
and then resume streaming. In this case, the stopping and restarting of streaming <em title="should" class="rfc2119">should</em>
cause <code>mute</code> and <code>unmute</code> events to fire on the Track in question. </li>
<li>Return a <code>BlobEvent</code> event containing the <code>Blob</code> to the <i>resolver</i> object's <i>resolve()</i> method.</li></dd>
<dt>Promise grabFrame()</dt>
<dd>When the <code>grabFrame()</code> method of an <code>ImageCapture</code> object is invoked, a new <i>Promise</i> object is returned. If the <code>readyState</code> of the <code>VideoStreamTrack</code> provided in the contructor is not "live", the UA <em title="must" class="rfc2119">must</em> return an <code>ImageCaptureErrorEvent</code> event to the <i>resolver</i> object's <i>reject()</i> method with a
new <code>ImageCaptureError</code> object whose <code>code</code> is set to INVALID_TRACK. If the UA is unable to execute the <code>grabFrame()</code> method for any
other reason, then the UA <em title="must" class="rfc2119">must</em> return an <code>ImageCaptureErrorEvent</code> event to the <i>resolver</i> object's <i>reject()</i> method with a
new <code>ImageCaptureError</code> object whose <code>code</code> is set to FRAME_ERROR. Otherwise it <em title="must" class="rfc2119">must</em>
queue a task, using the DOM manipulation task source, that runs the following steps:
<ol>
<li>Gather data from the <code>VideoStreamTrack</code> into an <code>ImageData</code> object (as defined in [[!CANVAS-2D]]) containing a single still frame in RGBA format. The <code>width</code> and <code>height</code> of the
<code>ImageData</code> object are derived from the constraints of the <code>VideoStreamTrack</code>. </li>
<li>Return a <code>FrameGrabEvent</code> event containing the <code>ImageData</code> to the <i>resolver</i> object's <i>resolve()</i> method. {Note: <code>grabFrame()</code> returns data only once upon being invoked.}</li>
</dd>
</dl>
</section>
Examples
-------
##### Taking a picture if Red Eye Reduction is activated
<pre class='example'>
navigator.getUserMedia({video: true}, gotMedia, failedToGetMedia);
function gotMedia(mediastream) {
//Extract video track.
var videoDevice = mediastream.getVideoTracks()[0];
// Check if this device supports a picture mode...
var captureDevice = new ImageCapture(videoDevice);
if (captureDevice) {
captureDevice.onphoto = showPicture;
if (captureDevice.photoOptions.redEyeReduction) {
captureDevice.setOptions({redEyeReductionSetting:true});
}
else
console.log('No red eye reduction');
captureDevice.onoptions = function(){
if (captureDevice.photoOptions.redEyeReduction.value)
captureDevice.takePhoto();
}
}
}
function showPicture(e) {
var img = document.querySelector("img");
img.src = URL.createObjectURL(e.data);
}
function failedToGetMedia{
console.log('Stream failure');
}
</pre>
##### Grabbing a Frame for Post-Processing
<pre class='example'>
navigator.getUserMedia({video: true}, gotMedia, failedToGetMedia);
function gotMedia(mediastream) {
//Extract video track.
var videoDevice = mediastream.getVideoTracks()[0];
// Check if this device supports a picture mode...
var captureDevice = new ImageCapture(videoDevice);
if (captureDevice) {
captureDevice.onframe = processFrame;
captureDevice.grabFrame();
}
}
function processFrame(e) {
imgData = e.imageData;
width = imgData.width;
height = imgData.height;
for (j=3; j < imgData.width; j+=4)
{
// Set all alpha values to medium opacity
imgData.data[j] = 128;
}
// Create new ImageObject with the modified pixel values
var canvas = document.createElement('canvas');
ctx = canvas.getContext("2d");
newImg = ctx.createImageData(width,height);
for (j=0; j < imgData.width; j++)
{
newImg.data[j] = imgData.data[j];
}
// ... and do something with the modified image ...
}
function failedToGetMedia{
console.log('Stream failure');
}
</pre>
##### Repeated grabbing of a frame
<pre class='example'>
<html>
<body>
<p><canvas id="frame"></canvas></p>
<button onclick="stopFunction()">Stop frame grab</button>
<script>
var canvas = document.getElementById('frame');
navigator.getUserMedia({video: true}, gotMedia, failedToGetMedia);
function gotMedia(mediastream) {
//Extract video track.
var videoDevice = mediastream.getVideoTracks()[0];
// Check if this device supports a picture mode...
var captureDevice = new ImageCapture(videoDevice);
var frameVar;
if (captureDevice) {
captureDevice.onframe = processFrame;
frameVar = setInterval(captureDevice.grabFrame(), 1000);
}
}
function processFrame(e) {
imgData = e.imageData;
canvas.width = imgData.width;
canvas.height = imgData.height;
canvas.getContext('2d').drawImage(imgData, 0, 0,imgData.width,imgData.height);
}
function stopFunction(e) {
clearInterval(myVar);
}
</script>
</body>
</html>
</pre>
##### Taking a picture if Red Eye Reduction is activated using promises
<pre class='example'>
navigator.getUserMedia({video: true}, gotMedia, failedToGetMedia);
function gotMedia(mediastream) {
//Extract video track.
var videoDevice = mediastream.getVideoTracks()[0];
// Check if this device supports a picture mode...
var captureDevice = new ImageCapture(videoDevice);
if (captureDevice) {
if (captureDevice.photoOptions.redEyeReduction) {
captureDevice.setOptions({redEyeReductionSetting:true});
}
else
console.log('No red eye reduction');
captureDevice.onoptions = function(){
if (captureDevice.photoOptions.redEyeReduction.value)
captureDevice.takePhoto().then(showPicture(blob),function(error){alert("Failed to take photo");});
}
}
}
function showPicture(e) {
var img = document.querySelector("img");
img.src = URL.createObjectURL(e.data);
}
function failedToGetMedia{
console.log('Stream failure');
}
</pre>
</body>
</html>