该软件包的第一个目标来自具有JS库,该库可以通过HTML5视频和帆布元素通过浏览器来捕获手机或台式摄像头的图片。因此,我不必使用本机navigator.mediaDevices.getUserMedia()和管理stream和constraints ,而需要将其抽象为一个小的lib,该lib可以在相机之间切换并获得所需的分辨率。
另一个JS摄像头?是的!我找到了WebCAMJS和JPEG_CAMERA,但我需要轻松地从相机environment和user切换。您需要建立getusermedia()的约束...另一个需求是拥有一个sizeFactor而不是固定的“宽度”和“高度”,而“宽度”和“高度”无法符合相机可以选择的分辨率之比。
facing mode或deviceId摄像头之间进行选择,请返回默认摄像头。ideal resolution ,回到默认分辨率。maximum resolution ,回到默认分辨率。jpg或png之间的DataUri image format类型。jpg ,请选择compression value是[0,1]之间。image mirror 。 https://mabelanger.github.io/jslib-html5-camera-photo/
https://caniuse.com/#search = getusermedia
...(2018年4月)
| facing_modes [] | 描述 |
|---|---|
| 用户 | 来源面对用户(一个自我查看摄像头)。 |
| 环境 | 来源远离用户(查看环境)。 |

SRC:https://www.w3.org/tr/mediacapture-streams/#dom-videofacingmodeenum
您可以将图书馆与香草JavaScript,React,jQuery,Angular ...一起使用...
npm install --save jslib-html5-camera-photoyarn add jslib-html5-camera-photo import CameraPhoto , { FACING_MODES , IMAGE_TYPES } from 'jslib-html5-camera-photo' ;
// get your video element with his corresponding id from the html
let videoElement = document . getElementById ( 'videoId' ) ;
// pass the video element to the constructor.
let cameraPhoto = new CameraPhoto ( videoElement ) ; cameraPhoto . startCamera ( cameraDevice , resolution )| 参数 | 描述 |
|---|---|
| CameradeVice | 是朝相机面向模式或DeviceID的string |
| 解决 | 是object分辨率ex:。 { width: 640, height: 480 } |
如果您没有指定任何首选分辨率和面向模式,则使用默认值。该功能返回承诺。如果承诺成功,如果您想使用它,它将为您提供流。如果失败,它将给您错误。
// default camera and resolution
cameraPhoto . startCamera ( )
. then ( ( stream ) => { /* ... */ } )
. catch ( ( error ) => { /* ... */ } ) ; // environment (camera point to environment)
cameraPhoto . startCamera ( FACING_MODES . ENVIRONMENT , { } )
. then ( ( stream ) => { /* ... */ } )
. catch ( ( error ) => { /* ... */ } ) ;
// OR user (camera point to the user)
cameraPhoto . startCamera ( FACING_MODES . USER , { } )
. then ( ( stream ) => { /* ... */ } )
. catch ( ( error ) => { /* ... */ } ) ; 您可以指定要使用的DeviceID(相机),而不是面对模式。要了解设备ID,您可以使用枚举可用摄像机获取它们的列表,因此您可以使用deviceId启动相机而不是面对模式,例如
// OR specify the deviceId (use a specific camera)
const deviceId = 'the_string_of_device_id' ;
cameraPhoto . startCamera ( deviceId , { } )
. then ( ( stream ) => { /* ... */ } )
. catch ( ( error ) => { /* ... */ } ) ; // example of ideal resolution 640 x 480
cameraPhoto . startCamera ( facingMode , { width : 640 , height : 480 } )
. then ( ( stream ) => { /* ... */ } )
. catch ( ( error ) => { /* ... */ } ) ; 它将尝试宽度[3840, 2560, 1920, 1280, 1080, 1024, 900, 800, 640, default] PX的范围以最大宽度为3840 px,如果不能,则为2560 px,等于相机默认值的后退值。 facingmode是可选的。
// It will try the best to get the maximum resolution with the specified facingMode
cameraPhoto . startCameraMaxResolution ( cameraDevice )
. then ( ( stream ) => { /* ... */ } )
. catch ( ( error ) => { /* ... */ } ) ; 返回相机当前帧的dataUri 。使用该函数使用相应的属性构建配置对象。要使用默认值,只需输入参数:
SizeFactor (数字):用于获得所需的分辨率。例如, 1尺寸因子获得相同的相机分辨率,而0.5的尺寸因子获得相机的一半分辨率。 sizeFactor可以在]0, 1]之间,默认值为1 。
图像类型(字符串):用于在jpg或png之间获取所需的图像类型。要指定图像类型使用常数image_types,例如指定jpg格式使用image_types.jpg。默认图像类型是png 。
想象力压缩(数字):选择jpg时用于获得所需的压缩。选择[0, 1] ,1是最大的压缩,0是最小值。默认值的想象压缩为0.92 。
Isimagemirror (布尔值):用于在设置为true时获得图像镜, dataUri的结果是实际摄像机数据的镜像。许多使用摄像机镜像等相机等软件等...请注意,如果您想启用此选项,为了与摄像机视频保持一致,则需要使用CSS transform: rotateY(180deg)到<video>标签来镜像流,因为流不镜像。它仅适用于Canvas DataUri。默认值为false (无镜像)。
| image_types [] | 描述 |
|---|---|
| JPG | 将image/jpeg设置为数据URI |
| PNG | 将image/png设置为数据URI(默认值) |
// Use all the default value
const config = { } ;
let dataUri = cameraPhoto . getDataUri ( config ) ;
// OR
// Specify sizeFactor, imageType, imageCompression, isImageMirror
const config = {
sizeFactor : 1 ;
imageType : IMAGE_TYPES . JPG
imageCompression : .95 ;
isImageMirror : false ;
}
let dataUri = cameraPhoto . getDataUri ( config ) ; 函数返回null如果不存在流(未启动相机)或具有相机设置属性的对象(factratio,framerate,height,width)。
let cameraSettigs = cameraPhoto . getCameraSettings ( ) ;
if ( cameraSettigs ) {
let { aspectRatio , frameRate , height , width } = cameraSettigs ;
let settingsStr =
`aspectRatio: ${ aspectRatio } ` +
`frameRate: ${ frameRate } ` +
`height: ${ height } ` +
`width: ${ width } ` ;
console . log ( settingsStr ) ;
} enumerateCameras()返回承诺,该承诺接收了一系列MediaDeviceInfo IE:。 {kind, label, deviceId}当承诺实现时。数组中的每个对象都描述了可用的摄像头之一(仅授予许可的设备类型是“可用的”)。订单很重要 - 默认捕获设备将首先列出。如果相机打开,它只会返回承诺。如果相机接近,则确保在返回承诺之前授予相机:进行持续20毫秒的相机的启动/停止周期。
cameraPhoto . enumerateCameras ( )
. then ( ( cameras ) => {
cameras . forEach ( ( camera ) => {
let { kind , label , deviceId } = camera ;
let cameraStr = `
kind: ${ kind }
label: ${ label }
deviceId: ${ deviceId }
` ;
console . log ( cameraStr )
} ) ;
} ) 您可以下载所拍摄的DataUri的照片,然后将其传递给downloadPhoto()函数。
import { downloadPhoto } from 'jslib-html5-camera-photo' ;
let dataUri = cameraPhoto . getDataUri ( config ) ;
downloadPhoto ( dataUri , prefixFileName , number ) ;
// The filename will be saved as the format :
` ${ prefixFileName } - ${ number } .jpg|png}` downloadPhoto()函数的参数
| 参数 | 描述 |
|---|---|
| DataUri | 是照片的数据图 |
| prefixFilename | 是文件名的string前缀 |
| 数字 | 是带有0个填充的文件名的integer前缀 |
停止相机的功能。如果成功,则不会返回值。如果他们没有相机停止,因为相机已经停止或从未启动,他们可能会失败。它将给出Error('no stream to stop!') 。请注意,每次我们启动相机时,它都会在内部使用此停止功能来应用新约束。
// It stop the camera
cameraPhoto . stopCamera ( )
. then ( ( ) => { /* ... */ } )
. catch ( ( error ) => { /* ... */ } ) ; <!-- needed to by the camera stream -->
< video id =" videoId " autoplay =" true " > </ video >
<!-- needed if you want to display the image when you take a photo -->
< img alt =" imgId " id =" imgId " >
<!--buttons to trigger the actions -->
< button id =" takePhotoButtonId " > takePhoto </ button >
< button id =" stopCameraButtonId " > stopCamera </ button > import CameraPhoto , { FACING_MODES } from 'jslib-html5-camera-photo' ;
// get video and image elements from the html
let videoElement = document . getElementById ( 'videoId' ) ;
let imgElement = document . getElementById ( 'imgId' ) ;
// get buttons elements from the html
let takePhotoButtonElement = document . getElementById ( 'takePhotoButtonId' ) ;
let stopCameraButtonElement = document . getElementById ( 'stopCameraButtonId' ) ;
// instantiate CameraPhoto with the videoElement
let cameraPhoto = new CameraPhoto ( videoElement ) ;
/*
* Start the camera with ideal environment facingMode
* if the environment facingMode is not available, it will fallback
* to the default camera available.
*/
cameraPhoto . startCamera ( FACING_MODES . ENVIRONMENT )
. then ( ( ) => {
console . log ( 'Camera started !' ) ;
} )
. catch ( ( error ) => {
console . error ( 'Camera not started!' , error ) ;
} ) ;
// function called by the buttons.
function takePhoto ( ) {
const config = { } ;
let dataUri = cameraPhoto . getDataUri ( config ) ;
imgElement . src = dataUri ;
}
function stopCamera ( ) {
cameraPhoto . stopCamera ( )
. then ( ( ) => {
console . log ( 'Camera stoped!' ) ;
} )
. catch ( ( error ) => {
console . log ( 'No camera to stop!:' , error ) ;
} ) ;
}
// bind the buttons to the right functions.
takePhotoButtonElement . onclick = takePhoto ;
stopCameraButtonElement . onclick = stopCamera ;带有React的项目与此库React-HTML5相机合作
import React from 'react' ;
import CameraPhoto , { FACING_MODES } from 'jslib-html5-camera-photo' ;
class App extends React . Component {
constructor ( props , context ) {
super ( props , context ) ;
this . cameraPhoto = null ;
this . videoRef = React . createRef ( ) ;
this . state = {
dataUri : ''
}
}
componentDidMount ( ) {
// We need to instantiate CameraPhoto inside componentDidMount because we
// need the refs.video to get the videoElement so the component has to be
// mounted.
this . cameraPhoto = new CameraPhoto ( this . videoRef . current ) ;
}
startCamera ( idealFacingMode , idealResolution ) {
this . cameraPhoto . startCamera ( idealFacingMode , idealResolution )
. then ( ( ) => {
console . log ( 'camera is started !' ) ;
} )
. catch ( ( error ) => {
console . error ( 'Camera not started!' , error ) ;
} ) ;
}
startCameraMaxResolution ( idealFacingMode ) {
this . cameraPhoto . startCameraMaxResolution ( idealFacingMode )
. then ( ( ) => {
console . log ( 'camera is started !' ) ;
} )
. catch ( ( error ) => {
console . error ( 'Camera not started!' , error ) ;
} ) ;
}
takePhoto ( ) {
const config = {
sizeFactor : 1
} ;
let dataUri = this . cameraPhoto . getDataUri ( config ) ;
this . setState ( { dataUri } ) ;
}
stopCamera ( ) {
this . cameraPhoto . stopCamera ( )
. then ( ( ) => {
console . log ( 'Camera stoped!' ) ;
} )
. catch ( ( error ) => {
console . log ( 'No camera to stop!:' , error ) ;
} ) ;
}
render ( ) {
return (
< div >
< button onClick = { ( ) => {
let facingMode = FACING_MODES . ENVIRONMENT ;
let idealResolution = { width : 640 , height : 480 } ;
this . startCamera ( facingMode , idealResolution ) ;
} } > Start environment facingMode resolution ideal 640 by 480 </ button >
< button onClick = { ( ) => {
let facingMode = FACING_MODES . USER ;
this . startCamera ( facingMode , { } ) ;
} } > Start user facingMode resolution default </ button >
< button onClick = { ( ) => {
let facingMode = FACING_MODES . USER ;
this . startCameraMaxResolution ( facingMode ) ;
} } > Start user facingMode resolution maximum </ button >
< button onClick = { ( ) => {
this . takePhoto ( ) ;
} } > Take photo </ button >
< button onClick = { ( ) => {
this . stopCamera ( ) ;
} } > Stop </ button >
< video
ref = { this . videoRef }
autoPlay = "true"
/>
< img
alt = "imgCamera"
src = { this . state . dataUri }
/>
</ div >
) ;
}
}
export default App ;您可以构建区域,然后将其提供:
$ npm run buildBrowser
$ npm run serve:dist或者,您可以复制存储库的DIST文件夹。
例子 :
< script src =" /jslib-html5-camera-photo.min.js " > </ script >
< script >
...
var FACING_MODES = JslibHtml5CameraPhoto . FACING_MODES ;
var cameraPhoto = new JslibHtml5CameraPhoto . default ( videoElement ) ;
...
</ script即使是Vanilla JS库,我也会选择创建反应应用程序的ENV开发人员,因为它易于使用,而且开发效率很高,但您不一定需要使用它来使用它。如果要修复错误或添加功能,请贡献:)