From 26dcc40535911da97a4c67b937f805195045196b Mon Sep 17 00:00:00 2001 From: felixindrawan Date: Wed, 26 Jun 2024 13:57:54 -0700 Subject: [PATCH 1/2] feat: update electron sample and docs --- hello-world/electron/README.md | 171 +++++++++++++++++------------- hello-world/electron/action.js | 55 +++++----- hello-world/electron/index.html | 22 ++-- hello-world/electron/package.json | 2 +- hello-world/electron/style.css | 9 +- 5 files changed, 140 insertions(+), 119 deletions(-) diff --git a/hello-world/electron/README.md b/hello-world/electron/README.md index 6743889c..4a3171cb 100644 --- a/hello-world/electron/README.md +++ b/hello-world/electron/README.md @@ -1,6 +1,14 @@ # Hello World Sample for Electron -[Electron](https://www.electronjs.org/) is a framework for creating native applications with web technologies. Follow this guide to learn how to implement Dynamsoft Barcode Reader JavaScript SDK (hereafter called "the library") into an Electron application. +[Electron](https://www.electronjs.org/) is a framework for creating native applications with web technologies. Follow this guide to learn how to implement [Dynamsoft Barcode Reader JavaScript SDK](https://www.dynamsoft.com/barcode-reader/sdk-javascript/) (hereafter called "the library") into a Next.js application. Note that in this sample, `TypeScript` is used. + +In this guide, we will be using [`dynamsoft-barcode-reader-bundle 10.2.1000`](https://www.npmjs.com/package/dynamsoft-barcode-reader-bundle/v/10.2.1000). + +> Note: +> +> If you’re looking to integrate DBR-JS into a framework that we don't yet have a sample, don't worry! We have a [comprehensive guide](https://www.dynamsoft.com/barcode-reader/docs/web/programming/javascript/user-guide/use-in-framework.html) that provides detailed instruction and best practices for a seamless integration into any frameworks! +> +> Additionally, we're here to help! Please don't hesitate to [contact us](#Support) for any support or questions you might have. ## Official Sample @@ -10,7 +18,23 @@ Make sure you have [node](https://nodejs.org/) installed. `node 16.20.1` and `electron 26.4.1` are used in this article. -## Initialize project +## Quick Start + +```cmd +npm install +npm start +``` +A window should open to view the sample application + +## Creating the sample project + +In this section, we will be creating an Electron application utilizing the Dynamsoft Barcode Reader bundle sdk. + +We'll be exploring how you could create a page that not only enables barcode scanning via a webcam or a built-in camera, but also decode barcodes from local images. + +By the end of this guide, you'll have a good understanding of the SDK and be ready to discover more ways to use it! + +### Initialize project ```cmd mkdir my-app && cd my-app @@ -19,27 +43,25 @@ npm init `npm init` will prompt you to configure some fields in your `package.json`. Note that the `entry point` should be `main.js` (it will be created later). -## install necessary libraries +### Install the necessary libraries ```cmd npm install electron --save-dev -npm install dynamsoft-capture-vision-std -npm install dynamsoft-image-processing -npm install dynamsoft-core -npm install dynamsoft-license -npm install dynamsoft-utility -npm install dynamsoft-barcode-reader -npm install dynamsoft-capture-vision-router -npm install dynamsoft-camera-enhancer +npm install dynamsoft-capture-vision-std -E +npm install dynamsoft-image-processing -E +npm install dynamsoft-barcode-reader-bundle -E ``` ## Start to implement ### Create a main.js file -As defined in the `package.json` file, `main.js` is the entry point of the application, we define it like this: +As defined in the `package.json` file, `main.js` is the entry point of the application. + +Create a `main.js` file at the root folder, and define it like this: ```javascript +/* /main.js */ const { app, BrowserWindow } = require("electron"); function createWindow() { @@ -80,30 +102,31 @@ The code basically opens `index.html` in a window. For more information, check o ### Create an `index.html` file -Create the page to be loaded in the created window. +As defined above, `index.html` is the file that will be loaded into the crated window. + +Create an `index.html` file at the root folder, and define it like this: ```html + - - + + Dynamsoft Barcode Reader Sample - Electron - - - - - - - + +

Hello World for Electron

-
+
+
Results: -
-
+
@@ -111,16 +134,28 @@ Create the page to be loaded in the created window. ### Create an `action.js` file -`index.html` will loads `action.js`, which makes use of libraries to read barcodes from a video input: +`index.html` will load `action.js`, which makes use of libraries to read barcodes from a video input. + +Create the `action.js` file at the root folder, and define it like this: ```javascript +/* /action.js */ +// Configures the paths where the .wasm files and other necessary resources for modules are located. +Dynamsoft.Core.CoreModule.engineResourcePaths = { + std: "./node_modules/dynamsoft-capture-vision-std/dist/", + dip: "./node_modules/dynamsoft-image-processing/dist/", + core: "./node_modules/dynamsoft-core/dist/", + license: "./node_modules/dynamsoft-license/dist/", + cvr: "./node_modules/dynamsoft-capture-vision-router/dist/", + dbr: "./node_modules/dynamsoft-barcode-reader/dist/", + dce: "./node_modules/dynamsoft-camera-enhancer/dist/" +}; + /** LICENSE ALERT - README * To use the library, you need to first specify a license key using the API "initLicense()" as shown below. */ -Dynamsoft.License.LicenseManager.initLicense( - "DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9" -); +Dynamsoft.License.LicenseManager.initLicense("DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9", true); /** * You can visit https://www.dynamsoft.com/customer/license/trialLicense?utm_source=github&product=dbr&package=js to get your own trial license good for 30 days. @@ -129,63 +164,41 @@ Dynamsoft.License.LicenseManager.initLicense( * LICENSE ALERT - THE END */ -Dynamsoft.Core.CoreModule.engineResourcePaths = { - std: "./node_modules/dynamsoft-capture-vision-std/dist/", - dip: "./node_modules/dynamsoft-image-processing/dist/", - core: "./node_modules/dynamsoft-core/dist/", - license: "./node_modules/dynamsoft-license/dist/", - cvr: "./node_modules/dynamsoft-capture-vision-router/dist/", - dbr: "./node_modules/dynamsoft-barcode-reader/dist/", - dce: "./node_modules/dynamsoft-camera-enhancer/dist/" -}; -(async function () { +// Optional. Preload "BarcodeReader" module for reading barcodes. It will save time on the initial decoding by skipping the module loading. +Dynamsoft.Core.CoreModule.loadWasm(["DBR"]); + +(async () => { try { // Create a `CameraEnhancer` instance for camera control and a `CameraView` instance for UI control. const cameraView = await Dynamsoft.DCE.CameraView.createInstance(); - const cameraEnhancer = await Dynamsoft.DCE.CameraEnhancer.createInstance( - cameraView - ); - document - .querySelector("#div-ui-container") - .append(cameraView.getUIElement()); // Get default UI and append it to DOM. + const cameraEnhancer = await Dynamsoft.DCE.CameraEnhancer.createInstance(cameraView); + // Get default UI and append it to DOM. + document.querySelector("#camera-view-container").append(cameraView.getUIElement()); // Create a `CaptureVisionRouter` instance and set `CameraEnhancer` instance as its image source. const cvRouter = await Dynamsoft.CVR.CaptureVisionRouter.createInstance(); cvRouter.setInput(cameraEnhancer); // Define a callback for results. - const resultReceiver = new Dynamsoft.CVR.CapturedResultReceiver(); - resultReceiver.onDecodedBarcodesReceived = (result) => { - if (!result.barcodeResultItems.length) return; - - const resultsContainer = document.querySelector("#div-results-container"); - resultsContainer.textContent = ''; - console.log(result); - for (let item of result.barcodeResultItems) { - resultsContainer.append( - `${item.formatString}: ${item.text}`, - document.createElement('br'), - document.createElement('hr'), - ); + cvRouter.addResultReceiver({ + onDecodedBarcodesReceived: (result) => { + if (!result.barcodeResultItems.length) return; + + const resultsContainer = document.querySelector("#results"); + resultsContainer.textContent = ''; + console.log(result); + for (let item of result.barcodeResultItems) { + resultsContainer.textContent += `${item.formatString}: ${item.text}\n\n`; + } } - }; - cvRouter.addResultReceiver(resultReceiver); + }); // Filter out unchecked and duplicate results. const filter = new Dynamsoft.Utility.MultiFrameResultCrossFilter(); - filter.enableResultCrossVerification( - "barcode", - true - ); // Filter out unchecked barcodes. + // Filter out unchecked barcodes. + filter.enableResultCrossVerification("barcode", true); // Filter out duplicate barcodes within 3 seconds. - filter.enableResultDeduplication( - "barcode", - true - ); - filter.setDuplicateForgetTime( - "barcode", - 3000 - ); + filter.enableResultDeduplication("barcode", true); await cvRouter.addResultFilter(filter); // Open camera and start scanning single barcode. @@ -201,19 +214,27 @@ Dynamsoft.Core.CoreModule.engineResourcePaths = { ### Create an `style.css` file -`index.html` will loads `style.css`, which defines the styles for the UI +`index.html` will load `style.css`, which defines the styles for the UI. + +Create the `style.css` file at the root folder. Note that this is customizable! ```css -#div-ui-container { +body { + text-align: center; +} + +#camera-view-container { width: 100%; height: 80vh; } -#div-results-container { +#results { width: 100%; height: 10vh; overflow: auto; + white-space: pre-wrap; } + ``` ## Run the application diff --git a/hello-world/electron/action.js b/hello-world/electron/action.js index caa09040..3a32e8f4 100644 --- a/hello-world/electron/action.js +++ b/hello-world/electron/action.js @@ -1,8 +1,19 @@ +// Configures the paths where the .wasm files and other necessary resources for modules are located. +Dynamsoft.Core.CoreModule.engineResourcePaths = { + std: "./node_modules/dynamsoft-capture-vision-std/dist/", + dip: "./node_modules/dynamsoft-image-processing/dist/", + core: "./node_modules/dynamsoft-core/dist/", + license: "./node_modules/dynamsoft-license/dist/", + cvr: "./node_modules/dynamsoft-capture-vision-router/dist/", + dbr: "./node_modules/dynamsoft-barcode-reader/dist/", + dce: "./node_modules/dynamsoft-camera-enhancer/dist/" +}; + /** LICENSE ALERT - README * To use the library, you need to first specify a license key using the API "initLicense()" as shown below. */ -Dynamsoft.License.LicenseManager.initLicense("DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9"); +Dynamsoft.License.LicenseManager.initLicense("DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9", true); /** * You can visit https://www.dynamsoft.com/customer/license/trialLicense?utm_source=github&product=dbr&package=js to get your own trial license good for 30 days. @@ -11,48 +22,34 @@ Dynamsoft.License.LicenseManager.initLicense("DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMD * LICENSE ALERT - THE END */ -Dynamsoft.Core.CoreModule.engineResourcePaths = { - std: "./node_modules/dynamsoft-capture-vision-std/dist/", - dip: "./node_modules/dynamsoft-image-processing/dist/", - core: "./node_modules/dynamsoft-core/dist/", - license: "./node_modules/dynamsoft-license/dist/", - cvr: "./node_modules/dynamsoft-capture-vision-router/dist/", - dbr: "./node_modules/dynamsoft-barcode-reader/dist/", - dce: "./node_modules/dynamsoft-camera-enhancer/dist/", -}; - -// Optional. Used to load wasm resources in advance, reducing latency between video playing and barcode decoding. +// Optional. Preload "BarcodeReader" module for reading barcodes. It will save time on the initial decoding by skipping the module loading. Dynamsoft.Core.CoreModule.loadWasm(["DBR"]); -// Defined globally for easy debugging. -let cameraEnhancer, cvRouter; (async () => { try { // Create a `CameraEnhancer` instance for camera control and a `CameraView` instance for UI control. const cameraView = await Dynamsoft.DCE.CameraView.createInstance(); - cameraEnhancer = await Dynamsoft.DCE.CameraEnhancer.createInstance(cameraView); + const cameraEnhancer = await Dynamsoft.DCE.CameraEnhancer.createInstance(cameraView); // Get default UI and append it to DOM. - document.querySelector("#div-ui-container").append(cameraView.getUIElement()); + document.querySelector("#camera-view-container").append(cameraView.getUIElement()); // Create a `CaptureVisionRouter` instance and set `CameraEnhancer` instance as its image source. - cvRouter = await Dynamsoft.CVR.CaptureVisionRouter.createInstance(); + const cvRouter = await Dynamsoft.CVR.CaptureVisionRouter.createInstance(); cvRouter.setInput(cameraEnhancer); // Define a callback for results. - cvRouter.addResultReceiver({ onDecodedBarcodesReceived: (result) => { - if (!result.barcodeResultItems.length) return; + cvRouter.addResultReceiver({ + onDecodedBarcodesReceived: (result) => { + if (!result.barcodeResultItems.length) return; - const resultsContainer = document.querySelector("#div-results-container"); - resultsContainer.textContent = ''; - console.log(result); - for (let item of result.barcodeResultItems) { - resultsContainer.append( - `${item.formatString}: ${item.text}`, - document.createElement('br'), - document.createElement('hr'), - ); + const resultsContainer = document.querySelector("#results"); + resultsContainer.textContent = ''; + console.log(result); + for (let item of result.barcodeResultItems) { + resultsContainer.textContent += `${item.formatString}: ${item.text}\n\n`; + } } - }}); + }); // Filter out unchecked and duplicate results. const filter = new Dynamsoft.Utility.MultiFrameResultCrossFilter(); diff --git a/hello-world/electron/index.html b/hello-world/electron/index.html index 6556bb0b..bc250794 100644 --- a/hello-world/electron/index.html +++ b/hello-world/electron/index.html @@ -2,23 +2,21 @@ - - + + Dynamsoft Barcode Reader Sample - Electron - - - - - - - + +

Hello World for Electron

-
+
+
Results: -
-
+
diff --git a/hello-world/electron/package.json b/hello-world/electron/package.json index 0e561b5a..c0e26d21 100644 --- a/hello-world/electron/package.json +++ b/hello-world/electron/package.json @@ -25,4 +25,4 @@ "dynamsoft-capture-vision-std": "1.2.10", "dynamsoft-image-processing": "2.2.30" } -} +} \ No newline at end of file diff --git a/hello-world/electron/style.css b/hello-world/electron/style.css index 864b4669..c0360ad1 100644 --- a/hello-world/electron/style.css +++ b/hello-world/electron/style.css @@ -1,10 +1,15 @@ -#div-ui-container { +body { + text-align: center; +} + +#camera-view-container { width: 100%; height: 80vh; } -#div-results-container { +#results { width: 100%; height: 10vh; overflow: auto; + white-space: pre-wrap; } From 69d7b731dc7f79d7d76ce7a812296f719510ab14 Mon Sep 17 00:00:00 2001 From: felixindrawan Date: Wed, 26 Jun 2024 14:13:19 -0700 Subject: [PATCH 2/2] fix: reversed globally defined vars --- hello-world/electron/action.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hello-world/electron/action.js b/hello-world/electron/action.js index 3a32e8f4..18998045 100644 --- a/hello-world/electron/action.js +++ b/hello-world/electron/action.js @@ -26,15 +26,18 @@ Dynamsoft.License.LicenseManager.initLicense("DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMD Dynamsoft.Core.CoreModule.loadWasm(["DBR"]); (async () => { + // Defined globally for easy debugging. + let cameraEnhancer, cvRouter; + try { // Create a `CameraEnhancer` instance for camera control and a `CameraView` instance for UI control. const cameraView = await Dynamsoft.DCE.CameraView.createInstance(); - const cameraEnhancer = await Dynamsoft.DCE.CameraEnhancer.createInstance(cameraView); + cameraEnhancer = await Dynamsoft.DCE.CameraEnhancer.createInstance(cameraView); // Get default UI and append it to DOM. document.querySelector("#camera-view-container").append(cameraView.getUIElement()); // Create a `CaptureVisionRouter` instance and set `CameraEnhancer` instance as its image source. - const cvRouter = await Dynamsoft.CVR.CaptureVisionRouter.createInstance(); + cvRouter = await Dynamsoft.CVR.CaptureVisionRouter.createInstance(); cvRouter.setInput(cameraEnhancer); // Define a callback for results.