How To Open Web/Mobile Camera And Take a Photo From SPFx WebPart

In this article, we will learn an interesting use case on how to open webcam or mobile camera and capture a photo from an SPFx web part. With SPFx being based on node packages, there are some very useful packages available which can be used to develop something which is other than data manipulation. 
 
It is assumed you have your SPFx development environment setup, if not please refer to this link
 
Step 1 - Create an SPFx solution
  • Create a project folder
  • run below command
  1. yo @microsoft/sharepoint  
Use the below standard options. Please make sure you select React as Javascript framework
 
Let's create a new SharePoint solution.
 
What is your solution name?
 
react-spfx-webcam
 
Which baseline packages do you want to target for your component(s)?
 
SharePoint Online only (latest)
 
Where do you want to place the files?
 
Use the current folder
 
Do you want to allow the tenant admin the choice of being able to deploy the solution to all sites immediately without running any feature deployment or adding apps in sites?
 
No
 
Will the components in the solution require permissions to access web APIs that are unique and not shared with other components in the tenant?
 
No
 
Which type of client-side component to create?
 
WebPart
 
Add new Web part to solution.
 
react-spfx-webcam.
 
What is your Web part name?
 
spFxwebcam
 
What is your Web part description?
 
spFxwebcam description
 
Which framework would you like to use?
 
React
 
Step 2  
 
Test your scaffolded project to make sure it is working 'gulp serve'
 
We should see local workbench opened in the browser and should be able to add the web part.
 
Step 3
 
Next thing we will do is to install the npm package which will allow the functionality of interacting with desktop/mobile camera.
 
We would be using react-webcam package at this link.
 
Go to node js command prompt, run the below command.
  1. npm install react-webcam  
Then run the below command.
  1. npm install @types/react-webcam  
 
Step 4 
 
Let us modify our React component. 
 
Path - \react-spfx-webcam\src\webparts\spFxWebCam\components\SpFxWebCam.tsx
 
First thing is to add and import the below 2 packages,
  1. import * as Webcam from "react-webcam";  
  2. import * as ReactDom from 'react-dom';  
Please note that package documentation has different syntax to import react-webcam package, but won't work with SPFx hence, use * to import all components in react-webcam.
 
Replace class definition line with below, what we are doing here is adding 2nd json object to hold data related to camera.
  1. export default class SpFxWebCam extends React.Component<ISpFxWebCamProps,{imageData: string, image_name:string,webcam:Webcam}> {  
Replace render method with below,
  1. public render(): React.ReactElement<ISpFxWebCamProps> {  
  2.     return (  
  3.       <div>  
  4.       <div className={ styles.spFxWebCam }>  
  5.         <div className={ styles.container }>  
  6.           <div className={ styles.row }>  
  7.             <div className={ styles.column }>  
  8.               <span className={ styles.title }>SPFx Web/Mobile Camera Demo </span>  
  9.               <p className={ styles.subTitle }>This is demo of how to open webcam and take photo from SPFx webpart.  
  10.               It will open camera in mobile web browser also</p>  
  11.               <a onClick={() => this.opencam()} className={ styles.button }>  
  12.                 <span className={ styles.label }>Open webcam</span>  
  13.               </a>  
  14.               <a onClick={() => this.capture()} className={ styles.button }>  
  15.                 <span className={ styles.label }>Take Photo</span>  
  16.               </a>  
  17.                 <a onClick={() => this.close()} className={ styles.button }>  
  18.                 <span className={ styles.label }>Close webcam</span>  
  19.               </a>  
  20.             </div>  
  21.           </div>  
  22.         </div>  
  23.       </div>  
  24.       <div id="camContainer">  
  25.         </div>  
  26.       <div id="capturedPhoto">   
  27.         </div>  
  28.       </div>  
  29.     );  
  30.   }  
Let us understand what are we doing here in render method. 
  • Added 3 buttons, open cam, take a photo and close cam and bind event handler to respective method. We will add events method in the next step.
  • Added one div camContainer 
    where we will add Camera object.
  • Added one div capturedPhoto 
    where we will render captured photo from camera.
Next, let us add supporting methods/events.
 
Open Cam
  1.   private opencam () {  
  2.       const element2: React.ReactElement<Webcam.WebcamProps > = React.createElement(  
  3.       Webcam,  
  4.       {  
  5.       height:350,  
  6.       width:350,  
  7.       screenshotFormat:"image/jpeg",  
  8.       ref:this.setRef,   
  9.       }  
  10.     );  
  11.     ReactDom.render(element2, document.getElementById("camContainer"));  
  12. }  
Here, we are creating new React Element and passing Webcam (which itself is a react component). Provide some configuration options as properties to Webcam component. You can find all the available properties at this link. All these properties can be used, but to keep it simple in the demo, we are using just a basic one.
 
SetRef  
  1. private setRef = (webcam) => {  
  2.   this.setState({webcam:webcam})  
  3. }  
This method is setting webcam reference which we just created above to the local component's variable webcam. This will allow us to use webcam properties and methods to the scope of this class (SpFxWebCam).
 
Capture
  1. private capture(){  
  2.     const imageSrc  =  this.state.webcam.getScreenshot();  
  3.     const element = React.createElement(  
  4.       'img',  
  5.       {  
  6.         src:imageSrc  
  7.       }  
  8.     );  
  9.     ReactDom.render(element, document.getElementById("capturedPhoto"));  
  10.   }  
This method will be called when user clicks on 'Take Photo' button. Here the first thing we are doing is using Webcam's getScreenshot method which will take a photo and return as base64 string of the captured photo. We are creating html element img using React.createElement method and providing src as base 64 string. And again finally rendering it to container which we defined in render method.
 
Close 
  1. public close(){  
  2. ReactDom.unmountComponentAtNode(document.getElementById('camContainer'));  
  3.   }  
This method will be called when the user clicks on 'Close webcam'. Here we are unmounting webcam from DOM. This will remove camera element from the page.
 
Step 5
 
Let us put it to the test, and run 'gulp serve'
 
We should see local workbench open, add web part like below.
 
 
 
Output
 
 
Click on Open Cam
 
 
Click on Take photo, it will capture photo and render the image below the camera canvas.
 
 
Click on Close cam, it will close the camera.
 
 
Photo mentions
 
Ved in yellow, Ansh in blue and me :). 
 
I have also tested this on a mobile Safari browser on the iPhone, it works as it does on the desktop. Of course we need to take care of mobile responsive CSS.
 
Looks easy, but it took me a while to put everything together being my first react web part. You can extend this web part to store the captured image in the SharePoint library. We can also do video recording using the stream method on the react-webcam package. We can always extend this web part to -
  • Take Photo and update User profile picture using Graph API.
  • Store photo in SharePoint document library using JSOM, REST API.
Hope you enjoyed reading!!!