1

I'm trying to make a functionality where I would like to allow users to save the captured images to the server. The general idea is:

  • Capture/Create an image on an HTML5 canvas using a button and When the image is completed, allow users to save the canvas as an image file to the server/person account.

This code will only let you to take your selfie and retake the image and capture it on the canvas. I want it to send every new image files when I press on the "Take Selfie Photo" button. I've been trying to use Anonymous Apex code to send image back using initial LinkedEntityId but not fully understand how it works.

This is my code and examples: https://studio.webcomponents.dev/preview/spOqm9nMonL1DtibANXA/src/app.js

.html

<template>
    <div class="wrapper" >
      <video width="320" height="240" autoplay></video>
      <canvas width="320" height="240"></canvas>
      <button class="button-0" onclick={clickPhoto}>Take Selfie Photo</button>
      <button class="button-1" onclick={retakePhoto}>Retake Selfie Photo</button>
    </div>
</template>

.js

import { LightningElement } from "lwc";

export default class App extends LightningElement {

  async connectedCallback() {
    const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: false });
    const video = this.template.querySelector('video');
    video.srcObject = stream;
  }

  // capture image
  clickPhoto() {
    const video = this.template.querySelector('video');
    const canvas = this.template.querySelector('canvas');
    canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
    const image_data_url = canvas.toDataURL('image/jpeg');
    // data url of the image
    console.log(image_data_url);
    const take = this.template.querySelector('.button-0');
    const retake = this.template.querySelector('.button-1');
    retake.style.display = "block";
    take.style.display = "none";
  }

  retakePhoto() {
    const canvas = this.template.querySelector('canvas');
    const context = canvas.getContext('2d');
    context.clearRect(0, 0, canvas.width, canvas.height); //clear html5 canvas
    const take = this.template.querySelector('.button-0');
    const retake = this.template.querySelector('.button-1');
    retake.style.display = "none";
    take.style.display = "block"; 
  }
}

Updates on apex code:

.anom.apex

// instance image in base64 
String base64 = 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII';

ContentVersion cv = new ContentVersion();
cv.VersionData = EncodingUtil.base64Decode(base64);
cv.Title = 'image.png';
cv.PathOnClient = 'image.png';
cv.IsMajorVersion = false;
insert cv;
System.debug('ContentVersion');
System.debug(cv.Id);

ContentDocumentLink cdl = new ContentDocumentLink();
cdl.ContentDocumentId = [
      SELECT ContentDocumentId 
      FROM ContentVersion 
      WHERE Id =: cv.Id
].ContentDocumentId;
cdl.LinkedEntityId = ''; // instance ID
cdl.ShareType = 'V';
cdl.Visibility = 'AllUsers';
insert cdl;
System.debug('ContentDocumentLink');
System.debug(cdl.Id);

.cls

public with sharing class CustomUploadFile {
    @AuraEnabled
    public static String uploadFile(String fileName, String base64Data, Id recordId) {
        // Decoding the base64Data
        base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8');
        ContentVersion cv = new ContentVersion();
        cv.Title = fileName;
        cv.PathOnClient = '/' + fileName;
        // cv.FirstPublishLocationId = recordId;
        cv.FirstPublishLocationId = '';
        cv.VersionData = EncodingUtil.base64Decode(base64Data);
        cv.IsMajorVersion = true;
        Insert cv;
        return 'File upload successfully!';
    }
}
6
  • 1
    What Apex have you tried so far?
    – sfdcfox
    Commented Jun 2, 2022 at 21:13
  • 1
    Also, have you seen this regarding the upload process?
    – sfdcfox
    Commented Jun 2, 2022 at 21:15
  • Hey @sfdcfox! I just put a update on the apex code. In my apex code, I'm using random base64(image) to upload to the LinkedEntityId. But I don't want to use base64 if is possible to just upload the canvas image after pressing the "Take Selfie Photo" button.
    – Ian Lee
    Commented Jun 2, 2022 at 21:23
  • 1
    You can't send binary data, as my linked answer states. The data payload is JSON-encoded, so you need to use the data URL's content (which is also base-64 encoded already) to upload the file.
    – sfdcfox
    Commented Jun 2, 2022 at 21:32
  • 1
    The class looks fine, just don't forget to create the ContentDocumentLink if you want to like the field to the record.
    – sfdcfox
    Commented Jun 2, 2022 at 21:54

0

You must log in to answer this question.

Browse other questions tagged .