Copyright © 2012-2013 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C liability, trademark and document use rules apply.
This document specifies the takePhoto() and getFrame() methods, and corresponding camera settings for use with MediaStreams as defined in Media Capture and Streams [GETUSERMEDIA].
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This is the first publication of this document as a Working Draft, and is still subject to potentially large changes; among other things, the Working Groups are discussing the opportunity to use DOM Promises instead of the current even-based approach.
This document was published by the Web Real-Time Communication Working Group and Device APIs Working Group as a First Public Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-media-capture@w3.org (subscribe, archives). All comments are welcome.
Publication as a First Public Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by groups operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures (Web Real-Time Communication Working Group, Device APIs Working Group) made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
The API defined in this document takes a valid MediaStream and returns an encoded image in the form of a Blob (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.
[Constructor(VideoStreamTrack track)]
interface ImageCapture : EventTarget {
readonly attribute PhotoSettingsOptions photoSettingsOptions;
readonly attribute VideoStreamTrack videoStreamTrack;
attribute EventHandler onphoto;
attribute EventHandler onerror;
attribute EventHandler onphotosettingschange;
attribute EventHandler onframegrab;
void setOptions (PhotoSettings? photoSettings);
void takePhoto ();
void getFrame ();
};onerror of type EventHandler, ImageCaptureErrorEvent. The handler should expect to get a ImageCaptureError object as its first parameter.onframegrab of type EventHandler, FrameGrabEvent. The handler should expect to get a FrameGrabEvent object as its first parameter.onphoto of type EventHandler, BlobEvent. The handler should expect to get a BlobEvent object as its first parameter.onphotosettingschange of type EventHandler, SettingsChangeEvent.photoSettingsOptions of type PhotoSettingsOptions, readonly videoStreamTrack of type VideoStreamTrack, readonly getFramegetFrame() method of an ImageCapture object is invoked, then if the readyState of the VideoStreamTrack provided in the contructor is not "live", the UA must fire a ImageCaptureErrorEvent event at the ImageCapture object with a
new ImageCaptureError object whose code is set to INVALID_TRACK. If the UA is unable to execute the getFrame() method for any
other reason, then the UA must fire a ImageCaptureErrorEvent event at the ImageCapture object with a
new ImageCaptureError object whose code is set to FRAME_GRAB_ERROR. Otherwise it must
queue a task, using the DOM manipulation task source, that runs the following steps:
VideoStreamTrack into a ImageData object (as defined in [CANVAS-2D]) containing a single still frame in RGBA format. The width and height of the
ImageData object are derived from the constraints of the VideoStreamTrack. FrameGrabEvent event containing the ImageData to the onframegrab event handler (if specified). {Note: getFrame() returns data only once upon being invoked.}voidsetOptionssetOptions() method of an ImageCapture object is invoked, then
then a valid PhotoSettings object must be passed in the method to the
ImageCapture object. If the UA can successfully apply the settings, then the UA must fire a SettingsChangeEvent event at the
onphotosettingschange event handler (if specified). If the UA cannot successfully apply the settings, then the UA
must fire a ImageCaptureErrorEvent at the ImageCapture object whose code is set to SETTINGS_ERROR. | Parameter | Type | Nullable | Optional | Description |
|---|---|---|---|---|
| photoSettings | | ✔ | ✘ |
voidtakePhototakePhoto() method of an ImageCapture object is invoked,
then if the readyState of the VideoStreamTrack provided in the constructor is not "live", the UA must fire a ImageCaptureErrorEvent event at the ImageCapture object with a
new ImageCaptureError object whose code is set to INVALID_TRACK. If the UA is unable to execute the takePhoto() method for any
other reason (for example, upon invocation of multiple takePhoto() method calls in rapid succession), then the UA must fire a ImageCaptureErrorEvent event at the ImageCapture object with a
new ImageCaptureError object whose code is set to PHOTO_ERROR.
Otherwise it must
queue a task, using the DOM manipulation task source, that runs the following steps:
VideoStreamTrack into a Blob 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 should
cause mute and unmute events to fire on the Track in question. BlobEvent event containing the Blob to the onphoto event handler (if specified).voidFrameGrabEvent[Constructor(DOMString type, optional FrameGrabEventInit frameGrabInitDict)]
interface FrameGrabEvent : Event {
readonly attribute ImageData imageData;
};imageData of type ImageData, readonly ImageData object whose length and height attributes indicates the dimensions of the captured frame. FrameGrabEventInit Dictionarydictionary FrameGrabEventInit : EventInit {
ImageData imageData;
};FrameGrabEventInit MembersimageData of type ImageDataImageData object containing the data to deliver via this event.ImageCaptureErrorEvent[Constructor(DOMString type, optional ImageCaptureErrorEventInit imageCaptureErrorInitDict)]
interface ImageCaptureErrorEvent : Event {
readonly attribute ImageCaptureError imageCaptureError;
};imageCaptureError of type ImageCaptureError, readonly ImageCaptureError object whose code attribute indicates the type of error occurrence. ImageCaptureErrorEventInit Dictionarydictionary ImageCaptureErrorEventInit : EventInit {
ImageCaptureError imageCaptureError;
};ImageCaptureErrorEventInit MembersimageCaptureError of type ImageCaptureErrorImageCaptureError object containing the data to deliver via this event.BlobEvent[Constructor(DOMString type, optional BlobEventInit blobInitDict)]
interface BlobEvent : Event {
readonly attribute Blob data;
};data of type Blob, readonly Blob 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 <img> tag. BlobEventInit Dictionarydictionary BlobEventInit : EventInit {
Blob data;
};BlobEventInit Membersdata of type BlobBlob object containing the data to deliver via this event.SettingsChangeEvent[Constructor(DOMString type, optional SettingsChangeEventInit photoSettingsInitDict)]
interface PhotoSettingsEvent : Event {
readonly attribute PhotoSettings photoSettings;
};photoSettings of type PhotoSettings, readonly PhotoSettings object whose type attribute indicates the current photo settings. SettingsChangeEventInit Dictionarydictionary SettingsChangeEventInit : EventInit {
PhotoSettings photoSettings;
};SettingsChangeEventInit MembersphotoSettings of type PhotoSettingsPhotoSettings object containing the data to deliver via this event.ImageCaptureError
The ImageCaptureError object is passed to an onerror event handler of an
ImageCapture object if an error occurred when the object was created or any of its methods were invoked.
[NoInterfaceObject]
interface ImageCaptureError {
const unsigned short FRAME_GRAB_ERROR = 1;
const unsigned short SETTINGS_ERROR = 2;
const unsigned short PHOTO_ERROR = 3;
const unsigned short ERROR_UNKNOWN = 4;
readonly attribute unsigned short code;
readonly attribute DOMString message;
};code of type unsigned short, readonly code attribute returns the appropriate code for the error event, derived from the constants defined in the ImageCaptureError interface.message of type DOMString, readonly message attribute must return an error message describing the details of the error encountered.ERROR_UNKNOWN of type unsigned shortImageCaptureError object must set its code value to this constant if an error occurred due to indeterminate cause upon invocation of any method of the ImageCapture interface.FRAME_GRAB_ERROR of type unsigned shortImageCaptureError object must set its code value to this constant if an error occurred upon invocation of the getFrame() method of the ImageCapture interface.PHOTO_ERROR of type unsigned shortImageCaptureError object must set its code value to this constant if an error occurred upon invocation of the takePhoto() method of the ImageCapture interface.SETTINGS_ERROR of type unsigned shortImageCaptureError object must set its code value to this constant if an error occurred upon invocation of the setOptions() method of the ImageCapture interface.MediaSettingsRangeinterface MediaSettingsRange {
readonly attribute unsigned long max;
readonly attribute unsigned long min;
readonly attribute unsigned long initial;
};initial of type unsigned long, readonly max of type unsigned long, readonly min of type unsigned long, readonly MediaSettingsItemThe MediaSettingsItem interface is now defined, which allows for a single setting to be managed.
interface MediaSettingsItem {
readonly attribute any value;
};value of type any, readonly PhotoSettingsOptionsThe PhotoSettingsOptions attribute of the ImageCapture 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:
| Mode | Kelvin range |
|---|---|
| incandescent | 2500-3500 |
| fluorescent | 4000-5000 |
| warm-fluorescent | 5000-5500 |
| daylight | 5500-6500 |
| cloudy-daylight | 6500-8000 |
| twilight | 8000-9000 |
| shade | 9000-10000 |
interface PhotoSettingsOptions {
attribute MediaSettingsItem autoWhiteBalanceMode;
attribute MediaSettingsRange whiteBalanceMode;
attribute ExposureMode autoExposureMode;
attribute MediaSettingsRange exposureCompensation;
attribute MediaSettingsRange iso;
attribute MediaSettingsItem redEyeReduction;
attribute MediaSettingsRange brightness;
attribute MediaSettingsRange constrast;
attribute MediaSettingsRange saturation;
attribute MediaSettingsRange sharpness;
attribute MediaSettingsRange imageHeight;
attribute MediaSettingsRange imageWidth;
};autoExposureMode of type ExposureMode, ExposureMode.autoWhiteBalanceMode of type MediaSettingsItem, brightness of type MediaSettingsRange, constrast of type MediaSettingsRange, exposureCompensation of type MediaSettingsRange, imageHeight of type MediaSettingsRange, imageWidth of type MediaSettingsRange, iso of type MediaSettingsRange, redEyeReduction of type MediaSettingsItem, saturation of type MediaSettingsRange, sharpness of type MediaSettingsRange, whiteBalanceMode of type MediaSettingsRange, WhiteBalanceModeEnum.ExposureModeenum ExposureModeEnum {
"frame-average",
"center-weighted",
"spot-metering"
};| Enumeration description | |
|---|---|
frame-average | Average of light information from entire scene |
center-weighted | Sensitivity concentrated towards center of viewfinder |
spot-metering | Spot-centered weighting |
PhotoSettingsThe PhotoSettings object is optionally passed into the ImageCapture.setOptions() method
in order to modify capture device settings specific to still imagery. Each of the attributes in this object
are optional.
dictionary PhotoSettings {
attribute boolean autoWhiteBalanceMode;
attribute unsigned long whiteBalanceMode;
attribute any autoExposureMode;
attribute unsigned long exposureCompensation;
attribute unsigned long iso;
attribute boolean redEyeReduction;
attribute unsigned long brightness;
attribute unsigned long constrast;
attribute unsigned long saturation;
attribute unsigned long sharpness;
attribute unsigned long imageHeight;
attribute unsigned long imageWidth;
};PhotoSettings MembersautoExposureMode of type attribute anyExposureModeEnum.autoWhiteBalanceMode of type attribute booleanbrightness of type attribute unsigned longconstrast of type attribute unsigned longexposureCompensation of type attribute unsigned longimageHeight of type attribute unsigned longimageWidth of type attribute unsigned longiso of type attribute unsigned longredEyeReduction of type attribute booleansaturation of type attribute unsigned longsharpness of type attribute unsigned longwhiteBalanceMode of type attribute unsigned longnavigator.getUserMedia({video: true}, gotMedia, failedToGetMedia);
function gotMedia(mediastream) {
//Extract video track. 'kind' attribute not checked because stream was created with video option only.
var videoDevice = mediastream.getTrackByID()[0];
// Check if this device supports a picture mode...
var pictureDevice = new ImageCapture(videoDevice);
if (pictureDevice) {
pictureDevice.onphoto = showPicture;
if (pictureDevice.photoSettingsOptions.redEyeReduction) {
pictureDevice.setOptions({redEyeReductionSetting:true});
}
else
console.log('No red eye reduction');
pictureDevice.onphotosettingschange = function(){
if (pictureDevice.photoSettingsOptions.redEyeReduction.value)
pictureDevice.takePhoto();
}
}
}
function showPicture(e) {
var img = document.querySelector("img");
img.src = URL.createObjectURL(e.data);
}
function failedToGetMedia{
console.log('Stream failure');
}navigator.getUserMedia({video: true}, gotMedia, failedToGetMedia);
function gotMedia(mediastream) {
//Extract video track. 'kind' attribute not checked because stream was created with video option only.
var videoDevice = mediastream.getTrackByID()[0];
// Check if this device supports a picture mode...
var pictureDevice = new ImageCapture(videoDevice);
if (pictureDevice) {
pictureDevice.onframegrab = processFrame;
pictureDevice.getFrame();
}
}
function processFrame(e) {
imgData = e.imageData;
width = imgData.width;
height = imgData.height;
for (j=3; j < imgData.length; 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.length; j++)
{
newImg.data[j] = imgData.data[j];
}
// ... and do something with the modified image ...
}
function failedToGetMedia{
console.log('Stream failure');
}