Oracle APEX 23 Course For Beginners

Oracle APEX 23 Course For Beginners
Oracle APEX 23 Course For Beginners

Friday, 13 January 2023

How to Integrate Front and Back Device Camera in Oracle APEX

You might be asked to develop an application in Oracle APEX that can take pictures using a device's camera and save them in the database. This section is intended for the same purpose. You will apply HTML5 features in combination with standard APEX functionality to take pictures from within an Oracle APEX application using a camera, and simultaneously put them in a database table. The exercise will use a table named DEMO_PRODUCT_INFO to demonstrate how to capture an image from your device's camera and store it in this table. If you are new to Oracle APEX, then watch this playlist.



Here are the steps for this exercise:

1.    Using the Shared Components | Static Application Files option, upload spin.min.js file from the CameraIntegration folder. The file contains instructions to display a wait spinner while AJAX requests are executing.

2.     Open Products page (Page 3) of the sales application in Page Designer. For further details of this application, watch this video.

3.     Add a button to the page using the following properties. The button will call Page 127 (to be created next). The target page will be used to activate device’s camera to take picture.

Property

Value

Button Name

CAMERA

Label

Snap Picture

Region

Breadcrumb

Button Position

Create

Button Template

Text with Icon

Hot

Yes

Icon

fa-camera

Action

Redirect to Page in this application

Target

Type=Page in this application

Page=127

Clear Cache=127


4.       Create a blank page (127), and set the following attributes for this page:

Property

Value

Name

Camera Integration

Title

Take Snapshot

Page Mode

Modal Dialog

Width

400

Height

700

File URLs (under JavaScript)

#APP_IMAGES#spin.min.js

Function and Global Variable Declaration

(under JavaScript)

var video = document.getElementById('myVideo');

var streamVideo;

var canvas = document.getElementById('myCanvas');

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

var spinner;

var spinForm = document.getElementById('wwvFlowForm');

var spinAttr = {

position: 'absolute', className: 'spinner', lines: 10, width: 10,  length: 30, top: '50%', left: '50%', radius: 40, opacity: 0.10, speed: 1, color: '#ffffff', rotate: 0

}


5.     Expand the Pre-Rendering node, and add the following After Header process. It’s an APEX Collection, which will be used to temporarily store the pictures you take. Each Collection in APEX can include one BLOB column (BLOB001). Here, you will use this column to store the binary representation of each picture. The code below creates an empty Collection named SNAPSHOT every time you access Page 127.

Property

Value

Name

Create Collection

Type

PL/SQL Code

Location

Local Database

PL/SQL Code

declare

  product_image constant apex_collections.collection_name%type := 'SNAPSHOT';

begin

  if not apex_collection.collection_exists(product_image) then

    apex_collection.create_collection(p_collection_name => product_image);

  ELSE

    apex_collection.delete_collection(p_collection_name => 'SNAPSHOT');

    apex_collection.create_collection(p_collection_name => product_image);

  end if;

end;

Point

After Header

 

6.    Create a Static Content region using the following attributes. The HTML5 video element enables camera streaming. The autoplay attribute used in this tag specifies that the camera will start playing as soon as it is ready. The canvas element is normally used to draw graphics, on the fly, via JavaScript.

Property

Value

Title

Camera

Type

Static Content

Text

<div style="text-align:center;">

  <video id="myVideo" width="250" height="300" autoplay></video>

  <canvas id="myCanvas" width="250" height="300" style="display:none;"></canvas>

</div>

Position

Content Body

Template

Standard


7.     Add two text field items as follows. These fields will receive product name and file name for the captured image.

Property

Value Text Field 1

Value Text Field 2

Name

P127_PRODUCT_NAME

P127_FILENAME

Type

Text Field

Text Field

Label

Product Name

File Name

Region

Camera

Camera

Template

Required - Floating

Required - Floating

Value Required

Yes

Yes

 

8.    Create a Buttons region using the following attributes. The region will hold two buttons to be created in the next step.

Property

Value

Title

Buttons

Type

Static Content

Position

Dialog Footer

Template

Buttons Container

 

9.    Add the following two buttons to the Buttons region. The TAKESNAP button will be used to take the snapshot via a Dynamic Action (Take Snap).

Property

Value Button 1

Value Button 2

Button Name

CANCEL

TAKESNAP

Label

Cancel

Take Snap

Region

Buttons

Buttons

Button Position

Below Region

Below Region

Button Template

Text

Text with Icon

Hot

No

Yes

Icon

-

fa-camera

Action

Defined by Dynamic Action

Defined by Dynamic Action

Execute Validations

Yes

Yes


10.  Create the Take Snap dynamic action as follows, which executes a JavaScript code to take pictures. The first line in this code displays a wait spinner through the spin.min.js file you uploaded in step 1. The apex.server.process function calls a PL/SQL on-demand (Ajax callback) process named GRAB_PICTURE – see Step 13.

Property

Value

Name

Take Snap

Event

Click

Selection Type

Button

Item(s)

TAKESNAP

Action

Execute JavaScript Code

Code

mySpinner = new Spinner(spinAttr).spin(spinForm);

ctx.drawImage(video, 0, 0, 250, 300);

video.style.display = 'none';

canvas.style.display = 'inline-block';

streamVideo.getTracks()[0].stop();


apex.server.process

(

    'GRAB_PICTURE',

    {p_clob_01: canvas.toDataURL().match(/,(.*)$/)[1]},

    {success: function(data) 

         {

              if (data.result == 'success')

              {

                   apex.submit('TAKESNAP');

              }

        }

    }

);


11.     Add another dynamic action to start the camera through JavaScript when the page loads. The navigator.mediaDevices.getUserMedia is a JavaScript method used to access a user's camera and microphone on a web page. It prompts the user for permission to use the camera and microphone, and if granted, returns a MediaStream object that can be used to access the camera and microphone data. The code below contains instructions for both the front and rear device cameras. However, for this exercise, we are using the back camera, and have disabled the code for the front camera (displayed in green color). Both code snippets use the getUserMedia() method to request access to the video stream from the device's camera. The option { video: { facingMode: "environment" } } is used to specify that we want to use the back camera. Once the user grants permission, the video stream is passed to the srcObject property of a <video> element, and the play() method is called to start the video.

Property

Value

Name

Start Camera

Event

Page Load

Action

Execute JavaScript Code

Code

// Use Rear Camera

// Check if the browser supports the mediaDevices API

if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) 

// get access to the device's camera

{ navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } }).then(function(stream) 

  {

    // Display the camera stream

    streamVideo = stream;

    video.srcObject = stream;

    video.play();

  }).catch(error => {

      // handle error

      console.log(error);

    });

} else {

  // the browser does not support the mediaDevices API

  console.log("Your browser does not support the MediaDevices API.");

}


/*

// Use Front Camera

// Check if the browser supports the mediaDevices API

if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) 

// get access to the device's camera

{ navigator.mediaDevices.getUserMedia({ video: true }).then(function(stream) 

  {

    // Display the camera stream

    streamVideo = stream;

    video.srcObject = stream;

    video.play();

  }).catch(error => {

      // handle error

      console.log(error);

  });

} else {

  // the browser does not support the mediaDevices API

  console.log("Your browser does not support the MediaDevices API.");

}

*/


12.    Add one more dynamic action to close the modal page when the Cancel button is clicked.

Property

Value

Name

Cancel Dialog

Event

Click

Selection Type

Button

Button

CANCEL

Action

Cancel Dialog

Event

Cancel Dialog


13.    Click the Processing tab, and add the following AJAX Call process. This process was referenced in the Take Snap dynamic action earlier. The PL/SQL code of this process uses the APEX_WEB_SERVICE API, which enables you to integrate other systems with Application Express.  The APEX_WEB_SERVICE.CLOBBASE64TBLOB is a function provided by the APEX_WEB_SERVICE package in the Oracle Application Express (APEX) framework. It is used to convert a Base64-encoded CLOB to a BLOB. This function takes in one parameter as an input, which is the base64-encoded CLOB and returns the BLOB. This function is useful when working with web services that return binary data, such as images or documents, encoded as Base64 strings. After converting a CLOB datatype into a BLOB, the BLOB is inserted in the SNAPSHOT APEX collection. A CLOB (Character Large Object) is a data type used to store large amounts of character data in a database, while a BLOB (Binary Large Object) is a data type used to store large amounts of binary data. Converting a CLOB to a BLOB typically involves converting the character data to binary data. This can be done for a variety of reasons, such as to improve data storage efficiency, to improve data transfer performance, or to make the data more compatible with other systems or software.

Property

Value

Name

GRAB_PICTURE

Type

PL/SQL Code

Location

Local Database

PL/SQL Code

declare

  V_picture_clob clob;

  V_picture_blob blob;

begin

  V_picture_clob := apex_application.g_clob_01;

 

  V_picture_blob := apex_web_service.clobbase642blob(

     p_clob => V_picture_clob

  );

 

  apex_collection.add_member(

    p_collection_name => 'SNAPSHOT',

    p_blob001 => V_picture_blob

  );

 

  apex_json.open_object;

  apex_json.write(

    p_name => 'result',

    p_value => 'success'

  );

  apex_json.close_object;

exception

  when others then

    apex_json.open_object;

    apex_json.write(

      p_name => 'result',

      p_value => 'fail'

    );

    apex_json.close_object;

end;

Point

Ajax Callback


14.     Add the following process (under Processing) to get the captured image from the SNAPSHOT collection and put it into the DEMO_PRODUCT_INFO table.

Property

Value

Name

Save Picture

Type

PL/SQL Code

Location

Local Database

PL/SQL Code

BEGIN

    INSERT INTO DEMO_PRODUCT_INFO

   (product_name, filename, mimetype, image_last_update,

        Product_image

   )

   VALUES

   (:P127_PRODUCT_NAME, :P127_FILENAME||'.jpg',  'image/jpeg',

     sysdate, (SELECT blob001 FROM apex_collections

                       WHERE collection_name = 'SNAPSHOT')

    );

  -- Delete APEX collection

  IF apex_collection.collection_exists(p_collection_name => 'SNAPSHOT') THEN

    apex_collection.delete_collection(p_collection_name => 'SNAPSHOT');

  END IF;

END;

Sequence

10

Point

Processing

When Button Pressed

TAKESNAP

 

15.    Add the following process to complete the image-capturing process. This process, which is to be placed after the Save Picture process, will close the modal page after taking the snapshot.

 Property

Value

Name

Close Dialog

Type

Close Dialog

Sequence

20

Point

Processing


16.    One last step that you need to perform is to automatically refresh the reports page to display the pictures you take. Open the Products page (Page 3) in page designer to add the following dynamic action.

Property

Value

Name

Refresh Report

Event

Dialog Closed

Selection Type

Button

                                 Button

CAMERA

Action

Refresh

Selection Type

Region

Region

Products

Run the application on your laptop with a camera, or on your Smartphone. Click the Products menu item. On the Products report page (Page 3), click the Snap Picture button that was added to the page in Step 3. Your browser might ask you to allow access to your device's camera. After granting access, the video should start playing on the modal page. Enter something in the Product Name and File Name text fields. Do not append an extension to the file name, because a .jpg extension will be added to it by default – see the Save Picture process. Take a picture by clicking the Take Snap button. The picture will be taken and you will be landed back on Page 3, where you will see the picture added to the interactive report.


For Visual Instruction Watch This Video 

Display Data Dynamically In A Gauge Chart

In this tutorial, we will learn how to display customer's ordered data in a gauge chart dynamically. As you choose a customer name from ...