El primer objetivo de este paquete proviene de la necesidad de tener una biblioteca JS que pueda ayudarme a capturar una imagen desde la cámara móvil o de escritorio a través del navegador con los elementos de video y lienzo HTML5. Entonces, en lugar de usar el navigator.mediaDevices.getUserMedia() y administrar la stream y las constraints , necesito una abstracción en una pequeña lib que pueda cambiar entre la cámara y obtener la resolución deseada.
¿Otra cámara JS? ¡Sí! Encontré webcamjs y jpeg_camera, pero necesito cambiar fácilmente del environment de la cámara y user . Debe construir la restricción para getUsermedia () ... otra necesidad es tener un sizeFactor en lugar de una fijación de 'ancho' y 'altura' que no pueda caber con la relación de la resolución que la cámara puede elegir.
facing mode o la cámara deviceId , vuelva a la cámara predeterminada.ideal resolution , vuelva a la resolución predeterminada.maximum resolution de la cámara, vuelva a la resolución predeterminada.image format de DataUri entre jpg o png .jpg , elija el compression value es entre [0, 1].image mirror de DataUri si desea obtener un reflejo de datos de la cámara. https://mabelanger.github.io/jslib-html5-camera-photo/
https://caniuse.com/#search=getusermedia
... (como abril de 2018)
| Facing_Modes [] | Descripción |
|---|---|
| USUARIO | La fuente está mirando hacia el usuario (una cámara de visión propia). |
| AMBIENTE | La fuente se dirige lejos del usuario (viendo el entorno). |

src: https://www.w3.org/tr/mediacapture-streams/#dom-videofacingmodeenum
Puede usar la biblioteca con Vanilla 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 )| parámetros | Descripción |
|---|---|
| CameradeVice | ¿Es la string de la cámara? |
| resolución | Es la resolución object Ej:. { width: 640, height: 480 } |
Si no especifica ningún modo de resolución y enfrentamiento preferido, se usa el valor predeterminado. La función devuelve una promesa. Si las promesas, el éxito le dará la transmisión si desea usarla. Si falla, le dará el error.
// 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 ) => { /* ... */ } ) ; En lugar de enfrentar el modo, puede especificar el dispositivo (cámara) que desea usar. Para conocer la ID del dispositivo, puede obtener una lista de ellos utilizando ver enumerado las cámaras disponibles, para que pueda iniciar la cámara con el deviceId en lugar de la cara, por ejemplo,
// 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 ) => { /* ... */ } ) ; Intentará el rango de ancho [3840, 2560, 1920, 1280, 1080, 1024, 900, 800, 640, default] PX para tomar el ancho máximo de 3840 PX si no puede, 2560 px y así sucesivamente ... hasta la caída del valor predeterminado de la cámara. El Mode Facing es opcional.
// It will try the best to get the maximum resolution with the specified facingMode
cameraPhoto . startCameraMaxResolution ( cameraDevice )
. then ( ( stream ) => { /* ... */ } )
. catch ( ( error ) => { /* ... */ } ) ; Función que devuelva los dataUri de la trama actual de la cámara. Para usar esa función, cree el objeto de configuración con las propiedades correspondientes. Para usar el valor predeterminado, simplemente omita el parámetro:
SizeFactor (número): se usa para obtener una resolución deseada. Ejemplo, un factor de tamaño de 1 obtiene la misma resolución de la cámara, mientras que SizeFactor de 0.5 obtiene la mitad de la resolución de la cámara. El SizeFactor puede estar entre el rango de ]0, 1] y el valor predeterminado es 1 .
ImageType (cadena): se usa para obtener el tipo de imagen deseado entre jpg o png . Para especificar el Tipo de imaginación, use el constante Image_Types, por ejemplo para especificar el formato JPG, use image_types.jpg. El tipo de imaginación predeterminado es png .
ImageCompression (número): se usa para obtener la compresión deseada cuando se selecciona jpg . Elija una compresión entre [0, 1] , 1 es máximo, 0 es mínimo. El valor predeterminado de la imagen image es 0.92 .
Isimagemirror (booleano): se usa para obtener un espejo de imagen cuando se establece en true , el resultado de dataUri es el espejo de los datos de la cámara reales. Muchos software que usan el espejo de la cámara como el lugar de reunión, etc. Tenga en cuenta que si desea habilitar esta opción, para consistencia con el video de la cámara, debe usar transform: rotateY(180deg) a la etiqueta <Dídide> para reflejar la transmisión, porque la transmisión no está reflejada. Solo se aplica al lienzo datauri. El valor predeterminado es false (sin espejo).
| Image_types [] | Descripción |
|---|---|
| JPG | Establecer imagen image/jpeg en el URI de datos |
| Png | Establecer image/png en el URI de datos (el valor predeterminado) |
// 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 ) ; La función return NULL Si no existe una corriente (cámara no se inicia) o un objeto con los atributos de configuración de la cámara de (Aspectratio, Framerate, Altura, Ancho).
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() Devuelve una promesa que recibe una variedad de mediasDeviceInfo es decir:. {kind, label, deviceId} Cuando se cumple la promesa. Cada objeto en la matriz describe una de las cámaras disponibles (solo los tipos de dispositivos para los cuales se ha otorgado el permiso son "disponibles"). El pedido es significativo: los dispositivos de captura predeterminados se enumerarán primero. Si la cámara está abierta, solo le devolverá la promesa. Si la cámara está cerca, se asegura de que la cámara se otorgue antes de devolver la promesa, es decir:. Haga un ciclo de inicio/parada de la cámara que continúa durante 20 ms.
cameraPhoto . enumerateCameras ( )
. then ( ( cameras ) => {
cameras . forEach ( ( camera ) => {
let { kind , label , deviceId } = camera ;
let cameraStr = `
kind: ${ kind }
label: ${ label }
deviceId: ${ deviceId }
` ;
console . log ( cameraStr )
} ) ;
} ) Puede descargar la foto de DataUri que tomó y pasarla a la función 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}` los parámetros de la función downloadPhoto()
| parámetros | Descripción |
|---|---|
| datauri | Es datauri de la foto |
| juego de prefije | Es el prefijo string del nombre de archivo |
| número | Es el número de número integer del nombre de archivo con 0 relleno |
Función que detiene la cámara. Si tiene éxito, no se devuelve ningún valor. Puede fallar si no son una cámara para detenerse porque la cámara ya ha sido detenida o nunca ha comenzado. Dará un parámetro de Error('no stream to stop!') . Tenga en cuenta que cada vez que iniciamos la cámara, se usa internamente esta función de parada para poder aplicar nuevas restricciones.
// 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 ;Se construye un proyecto con React con esta biblioteca React-HTML5-Camera-Photo
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 ;Puedes construir el Dist y luego servirlo con:
$ npm run buildBrowser
$ npm run serve:distO puede copiar la carpeta DIST del repositorio.
Ejemplo :
< script src =" /jslib-html5-camera-photo.min.js " > </ script >
< script >
...
var FACING_MODES = JslibHtml5CameraPhoto . FACING_MODES ;
var cameraPhoto = new JslibHtml5CameraPhoto . default ( videoElement ) ;
...
</ scriptElijo el dev Dev de Create-React-App, incluso si es la biblioteca de Vanilla JS porque es fácil de usar y realmente eficiente de desarrollar, pero no necesariamente necesita reaccionar para usarla. Si desea solucionar el error o agregar funcionalidades, contribuya :)