Capture Image with LWC

Yes, you heard it right, we can capture image using LWC.This feature can be used by reps on the field to capture Images of a site or a receipt and store it on a record in Salesforce. And sales reps can collaborate with others and discuss about this image or a document via chatter or sharing the files.

?

?Photo can be captured using desktop camera or default camera of your mobile.For mobile experience we can specify the mobile camera that should be used.

LWS needs to be enabled for clicking image using LWC.

The locker service currently rewrites most of the browsers?native javascript objects like the window, document, navigator etc. Therefore navigator cannot be used with Lightning locker,instead we will use LWS.

?Below is code to capture Photos using LWC-:

?<template>

    <lightning-card variant="Narrow" title="Upload Photo without canvas">

        <div class="camera-wrapper">

            <lightning-button label="Start Video" class="slds-m-left_xx-small" onclick={initCamera}></lightning-button>

            <lightning-button label="Stop Video" class="slds-m-left_xx-small" onclick={stopCamera}></lightning-button>

            <lightning-button label="Capture Image" class="slds-m-left_xx-small" onclick={captureImage}></lightning-button>

        </div>

        <div class="slds-grid slds-gutters">

            <div class="slds-col">

                <video class="videoElement" autoplay></video>

                <img src="" class="slds-hide imageElement" alt="captured image"/>

            </div>

        </div>

        <lightning-button variant="Save Photo" label="Save" title="titleName" onclick={handleSavePhotoClick}></lightning-button>

    </lightning-card>

</template>        

?Js file

import { LightningElement } from 'lwc';

import saveContactPhotoAttachment from '@salesforce/apex/Take_Photo_From_User.saveContactPhotoAttachment';

export default class AccessCamera extends LightningElement {

    videoElement;

    imageData;

    renderedCallback() {

        this.videoElement = this.template.querySelector('.videoElement');

    }

    async initCamera() {

        if (navigator.mediaDevices && navigator.mediaDevices) {

            try {

                this.videoElement.srcObject = await navigator.mediaDevices.getUserMedia({video: true, audio: false});

            } catch (error) {

                console.error('Error accessing camera: ', JSON.stringify(error));

            }

        } else {

            console.error('getUserMedia is not supported in this browser');

        }

    }

    async captureImage() {

        if(this.videoElement && this.videoElement.srcObject !== null) {

            const imageElement = document.createElement('img');

            imageElement.onload = () => {

                URL.revokeObjectURL(imageElement.src);

                this.imageData = this.getBase64Image(imageElement);

                const existingImageElement = this.template.querySelector('.imageElement');

                existingImageElement.src = imageElement.src;

                existingImageElement.classList.add('slds-show');

                existingImageElement.classList.remove('slds-hide');

            };

            imageElement.src = URL.createObjectURL(await this.getImageBlobFromVideo());

            this.template.querySelector('.slds-col').appendChild(imageElement); // Append image element to the DOM

        }

    }

    async getImageBlobFromVideo() {

        const canvas = document.createElement('canvas');

        canvas.width = this.videoElement.videoWidth;

        canvas.height = this.videoElement.videoHeight;

        canvas.getContext('2d').drawImage(this.videoElement, 0, 0);

        return new Promise((resolve) => {

            canvas.toBlob((blob) => {

                resolve(blob);

            }, 'image/png');

        });

    }

    getBase64Image(img) {

        const canvas = document.createElement('canvas');

        canvas.width = img.width;

        canvas.height = img.height;

        const ctx = canvas.getContext('2d');

        ctx.drawImage(img, 0, 0);

        const dataURL = canvas.toDataURL('image/png');

        return dataURL.replace(/^data:image\/(png|jpg);base64,/, '');

    }

    async stopCamera(){

        const video = this.template.querySelector(".videoElement");

        video.srcObject.getTracks().forEach((track) => track.stop());

        video.srcObject = null;

        this.hideImageElement();

    }

    hideImageElement(){

        const imageElement = this.template.querySelector('.imageElement');

        imageElement.setAttribute('src', "");

        imageElement.classList.add('slds-hide');

        imageElement.classList.remove('slds-show');

    }

    async handleSavePhotoClick() {

        const contactId = '0035i00001H41PyAAJ'; // Provide the actual contact Id here

        const fileName = 'ContactPhoto.png'; // Set the desired file name

        try {

            await saveContactPhotoAttachment({ contactId: contactId, imageData:  this.imageData, fileName: fileName });

            console.log('Image data saved as attachment related to contact record successfully');

            const video = this.template.querySelector(".videoElement");

            video.srcObject.getTracks().forEach((track) => track.stop());

            video.srcObject = null;

            this.hideImageElement();

        } catch (error) {

            console.error('Error saving image data as attachment related to contact record: ', error);

        }

    }

}

         

Code Explanation:

  1. Video Tag for Image Capture: The <video> tag is used to capture images. It's a standard HTML5 element used for multimedia playback, including video and, in this case, image capture.

  1. Image Element for Display: An <img> element is used to display the image that has been captured using the Lightning Web Component (LWC). This element is likely used to visually present the captured image to the user.

  1. Saving Image to Contact Record: Upon clicking the save button, the photo is saved on the Contact record. The Contact record ID is hardcoded in this example, but it's recommended to make it dynamic based on your application logic.

  1. Asynchronous Methods Using Async/Await: Methods are made asynchronous using async/await. As JavaScript is single-threaded, asynchronous code helps in improving user experience by allowing other operations to continue while waiting for certain tasks to complete.

  1. Storage of Images in Salesforce Database: Images are stored in the Salesforce database as blobs, which are binary large objects. These blobs are not encoded in base64 initially. Base64 encoding is used as the transfer mechanism for the image data.

Explanation of captureImage Method:

  1. Element Creation: The method begins by creating an element using document.createElement. This element is likely used for handling the captured image.

  1. URL Handling: On the onload event of the element, the code ensures that the URL is empty by using URL.revokeObjectURL. This step likely helps in managing memory and resources efficiently.

  1. Dimension and Context Setting: Next, the dimensions and context of the image element are set. This step involves configuring the size and properties of the image to be captured.

  1. Base64 Encoded Image Retrieval: The method retrieves the image in base64 encoded format. This format is commonly used for representing binary data in ASCII string format.

  1. Object URL Creation: createObjectURL() is used to create a reference to a File or Blob. This URL likely serves as a temporary reference to the captured image.

  1. Embedding Image Element in DOM: Finally, the image element is appended to the DOM using this.template.querySelector('.slds-col').appendChild(imageElement). This step ensures that the captured image is displayed within the Lightning Web Component.?

?

?

?

?

?


Harshvardhan Agrawal

Associate Software Engineer @OSI Digital || Undergraduate @BITS MESRA 2019 - 23 || 4 X Salesforce Certified Developer ( AI + PD1 + Admin)

1 个月

Hi Sakshi Nagpal, Thanks for the info, very useful, do you have any idea like how to save this image in a salesforce record in rich text field or to save in file and attach the file to a particular record? Thanks in Advance!

回复
Indranil Karmakar

Lead Software Engineer at Persistent Systems LTD || 6x Salesforce Certified || Salesforce Developer

10 个月

Where is the apex class??????????????

回复

要查看或添加评论,请登录

Sakshi Nagpal的更多文章

  • How AI has transformed our lives-How does ChatGPT works.

    How AI has transformed our lives-How does ChatGPT works.

    Transforming the Future: The Impact of AI on Our Everyday Lives Artificial Intelligence (AI) has indeed become a…

  • Handling Files in Salesforce

    Handling Files in Salesforce

    File storing strategy in Salesforce is a crucial component of effective data management and document handling within…

    14 条评论
  • What is the Maurity of your Rest API

    What is the Maurity of your Rest API

    if you are looking for a way to evaluate your Rest API, Richardson Maturity Model can help you in understanding the…

    1 条评论

社区洞察

其他会员也浏览了