Quantcast
Channel: Barcode – Dynamsoft Developers
Viewing all 145 articles
Browse latest View live

Java Programming: JNA vs. JNI on Windows

$
0
0

Some developers used JNA to call native C/C++ interfaces of Dynamsoft Barcode Reader in Java program. The app ran slowly and sometimes crashed. Based on the use case, I created a simple project for building JNA and JNI on Windows. The sample does not only show how to invoke native code but also share how to check the Java thread stack size and solve the stack overflow issue on Windows.

Download and Installation

Accessing Native Code via JNA and JNI

Open Eclipse to create a new project. The structures of JNA and JNI folders are almost the same.

eclipse project

Java code

Create the Java function decodefile() for JNA and JNI:

JNA JNI Java

C/C++ code

For JNA, you just need to create a standard function and export it. For JNI, you have to comply with the JNI naming convention.

JNA JNI native code

Building shared libraries with CMake

Copy shared libraries to <Project Root>/jna(jni)/platforms/win:

  • DBRx64.lib
  • DBRx86.lib
  • DynamsoftBarcodeReaderx64.dll
  • DynamsoftBarcodeReaderx86.dll

Create CMakeLists.txt:

cmake_minimum_required (VERSION 2.6)
project (dbr)
MESSAGE( STATUS "PROJECT_NAME: " ${PROJECT_NAME} )

# Check platforms
if (CMAKE_HOST_WIN32)
    set(WINDOWS 1)
    set(JAVA_HOME "E:/Program Files (x86)/Java/jdk1.8.0_191")
    set(JAVA_INCLUDE "${JAVA_HOME}/include")
    set(JAVA_INCLUDE_OS "${JAVA_HOME}/include/win32")
endif()

MESSAGE( STATUS "JAVA_INCLUDE: " ${JAVA_INCLUDE})

# Configure a header file to pass some of the CMake settings
# to the source code
configure_file (
    "${PROJECT_SOURCE_DIR}/BarcodeReaderConfig.h.in"
    "${PROJECT_BINARY_DIR}/BarcodeReaderConfig.h"
)

# Add search path for include and lib files
if(WINDOWS)
    link_directories("${PROJECT_SOURCE_DIR}/platforms/win" "${JAVA_HOME}/lib") 
    include_directories("${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/include" "${PROJECT_SOURCE_DIR}" "${JAVA_INCLUDE}" "${JAVA_INCLUDE_OS}")
endif()

# Add the executable
add_library(jnadbr SHARED NativeBarcodeReader.cxx)
if(WINDOWS)
    if(CMAKE_CL_64)
        target_link_libraries (jnadbr "DBRx64")
    else()
        target_link_libraries (jnadbr "DBRx86")
    endif()
endif()

# Set installation directory
set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/../")
if(WINDOWS)
    install (DIRECTORY "${PROJECT_SOURCE_DIR}/platforms/win/" DESTINATION "${CMAKE_INSTALL_PREFIX}" FILES_MATCHING PATTERN "*.dll")
    install (TARGETS jnadbr DESTINATION "${CMAKE_INSTALL_PREFIX}")
endif()

To build the shared library for JNI, replace ‘jnadbr’ with ‘jnidbr’.

Build the project for 64-bit Java runtime:

cd jna
mkdir build
cd build
cmake -G"Visual Studio 15 2017 Win64" .. 
cmake --build . --config Release --target install

Create Demo.java for test:

public static void main(String[] args) {
		int count = 1;
		
		JNABarcode jnaReader = new JNABarcode();
		
		System.out.println("JNA start.");
		long start = System.currentTimeMillis();
		for (int i = 0; i < count; i++) {
			jnaReader.decodefile();
		}
		long end = System.currentTimeMillis();
		System.out.println("JNA end. Time cost: " + (end - start) + "ms");
		
		JNIBarcode jniReader = new JNIBarcode();
		System.out.println("JNI start.");
		start = System.currentTimeMillis();
		for (int i = 0; i < count; i++) {
			jniReader.decodefile();
		}
		end = System.currentTimeMillis();
		System.out.println("JNI end. Time cost: " + (end - start) + "ms");
	}

Run the app:

javac -cp libs\jna-3.0.9.jar src\com\dynamsoft\*.java
java -cp libs\jna-3.0.9.jar;src\ com.dynamsoft.Demo

JNA init time

Why is running JNA much slower than running JNI?

The native code is the same, why the performance is different? The only possible reason is when calling the native method the first time it takes a long time to initialize the JNA environment.

jna

We can call the native method to initialize the JNA environment before measuring the performance.

JNA initialization

Build and rerun the app. The JNA performance of invoking native method looks no different to JNI.

JNA JNI performance

Now we get the conclusion that using JNA takes extra loading time.

Java VM Stack Overflow Exception

The stack overflow exception showed up when runtime environment switched from 64-bit to 32-bit.

JVM stack overflow

According to https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/crashes001.html, the issue is caused by thread stack size. To solve the issue, we’d better know the default thread stack size. Let’s try the following command:

Linux

java -XX:+PrintFlagsFinal -version | grep ThreadStackSize

Linux thread stack size

Windows

java -XX:+PrintFlagsFinal -version | findstr ThreadStackSize

Windows thread stack size

The value of stack size is 0 on Windows. Maybe the answer is in the source code.

Download and install TortoiseHg.

Get JVM source code:

hg clone http://hg.openjdk.java.net/jdk8/jdk8/hotspot/

Search for ‘stack size’ to find the following informative paragraph.

stack size on Windows

To verify whether the default stack size is 320K on Windows, I tried the code snippet located in os_windows.cpp:

typedef u_char* address;
#include <windows.h>

address current_stack_base() {
  MEMORY_BASIC_INFORMATION minfo;
  address stack_bottom;
  size_t stack_size;

  VirtualQuery(&minfo, &minfo, sizeof(minfo));
  stack_bottom =  (address)minfo.AllocationBase;
  stack_size = minfo.RegionSize;
  
  while( 1 )
  {
    VirtualQuery(stack_bottom+stack_size, &minfo, sizeof(minfo));
    if ( stack_bottom == (address)minfo.AllocationBase )
      stack_size += minfo.RegionSize;
    else
      break;
  }

#ifdef _M_IA64
#endif
  
  return stack_bottom + stack_size;
}

size_t sz;
  MEMORY_BASIC_INFORMATION minfo;
  VirtualQuery(&minfo, &minfo, sizeof(minfo));
  sz = (size_t)current_stack_base() - (size_t)minfo.AllocationBase;
  printf("The default Java thread stack size for this system is %u bytes(%u KB).\n", sz, sz / 1024);

To avoid stack overflow exception, we should allocate big chunks of memory on the heap instead of the stack.

memory allocation

Re-compile the native code in x86 mode:

cd jna
mkdir build
cd build
cmake .. 
cmake --build . --config Release --target install

Compile and run the Java code with 32-bit JDK:

"E:\Program Files (x86)\Java\jdk1.8.0_191\bin\javac.exe" -cp libs\jna-3.0.9.jar src\com\dynamsoft\*.java
"E:\Program Files (x86)\Java\jdk1.8.0_191\bin\java.exe" -cp libs\jna-3.0.9.jar;src\ com.dynamsoft.Demo

default stack size

We can see the default stack size is 320K by default on Windows. To enlarge the stack size, append -Xss option when running Java program:

"E:\Program Files (x86)\Java\jdk1.8.0_191\bin\java.exe" -Xss1024 -cp libs\jna-3.0.9.jar;src\ com.dynamsoft.Demo

References

Source Code

https://github.com/yushulx/jna-jni-windows

The post Java Programming: JNA vs. JNI on Windows appeared first on Code Pool.


How to Integrate Dynamsoft Barcode Reader into React Native Camera

$
0
0

If you are using React Native, you can quickly create a camera app with React Native Camera. In addition, React Native Camera component supports barcode scanning, face detection, and text recognition. This article shares how to replace the default barcode reading function with Dynamsoft Barcode Reader for Android.

How to Build a Camera App with React Native Camera

Follow the tutorial to create a new React Native project:

npm install -g react-native-cli
react-native init AwesomeProject
cd AwesomeProject

Install React Native Camera module:

npm install react-native-camera –save
react-native link react-native-camera

Read the documentation to get the code snippet of using RNCamera in App.js.

Build and run the Android camera app:

react-native run-android

You may get the error ‘Could not find play-services-basement.aar’:

gradle build error

Referring to StackOverflow, move jcenter() to the last place in repositories.

jcenter position

How to Integrate Dynamsoft Barcode Reader into React Native Camera

According to the sample code shown in the documentation, by default, we can use Google Mobile Vision to scan barcodes on Android:

<RNCamera
            <…>
            onGoogleVisionBarcodesDetected={({ barcodes }) => {
              console.log(barcodes)
            }}
        />

Let’s anatomize the source code and make Dynamsoft Barcode Reader work with the component.

How to return barcode results to JavaScript

Get started with ‘onGoogleVisionBarcodesDetected’.

google mobile vision

This is an event used to pass native barcode results from Java to JavaScript. The following code shows how to pack barcode types and values into an event:

@Override
  public void dispatch(RCTEventEmitter rctEventEmitter) {
    rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData());
  }

private WritableMap serializeEventData() {
    WritableArray barcodesList = Arguments.createArray();

    for (int i = 0; i < mBarcodes.size(); i++) {
      Barcode barcode = mBarcodes.valueAt(i);
      WritableMap serializedBarcode = Arguments.createMap();
      serializedBarcode.putString("data", barcode.displayValue);
      serializedBarcode.putString("type", BarcodeFormatUtils.get(barcode.format));
      barcodesList.pushMap(serializedBarcode);
    }

    WritableMap event = Arguments.createMap();
    event.putString("type", "barcode");
    event.putArray("barcodes", barcodesList);
    event.putInt("target", getViewTag());
    return event;
  }

How to detect barcodes?

When we set ‘onGoogleVisionBarcodesDetected’ to receive the callback, another property ‘googleVisionBarcodeDetectorEnabled’ will be true in RMCamera.js:

_convertNativeProps(props: PropsType) {
    const newProps = mapValues(props, this._convertProp);

    if (props.onBarCodeRead) {
      newProps.barCodeScannerEnabled = true;
    }

    if (props.onGoogleVisionBarcodesDetected) {
      newProps.googleVisionBarcodeDetectorEnabled = true;
    }

With @ReactProp annotation, the native setter will be called in CameraViewManager.java:

@ReactProp(name = "googleVisionBarcodeDetectorEnabled")
  public void setGoogleVisionBarcodeDetecting(RNCameraView view, boolean googleBarcodeDetectorEnabled) {
    view.setShouldGoogleDetectBarcodes(googleBarcodeDetectorEnabled);
  }

Hereafter, the instance of the barcode reader will be created in RNCameraView.java:

public void setShouldGoogleDetectBarcodes(boolean shouldDetectBarcodes) {
    if (shouldDetectBarcodes && mGoogleBarcodeDetector == null) {
      setupBarcodeDetector();
    }
    this.mShouldGoogleDetectBarcodes = shouldDetectBarcodes;
    setScanning(mShouldDetectFaces || mShouldGoogleDetectBarcodes || mShouldScanBarCodes || mShouldRecognizeText);
  }

When we start the camera preview, the barcode reader will work if it has been initialized in RNCameraView.java:

@Override
      public void onFramePreview(CameraView cameraView, byte[] data, int width, int height, int rotation) {
        boolean willCallGoogleBarcodeTask = mShouldGoogleDetectBarcodes && !googleBarcodeDetectorTaskLock && cameraView instanceof BarcodeDetectorAsyncTaskDelegate;
if (willCallGoogleBarcodeTask) {
          googleBarcodeDetectorTaskLock = true;
          BarcodeDetectorAsyncTaskDelegate delegate = (BarcodeDetectorAsyncTaskDelegate) cameraView;
          new BarcodeDetectorAsyncTask(delegate, mGoogleBarcodeDetector, data, width, height, correctRotation).execute();
        }

The BarcodeDetectorAsyncTask.java extends AsyncTask. The barcode decoding API runs in the background:

@Override
  protected SparseArray<Barcode> doInBackground(Void... ignored) {
    if (isCancelled() || mDelegate == null || mBarcodeDetector == null || !mBarcodeDetector.isOperational()) {
      return null;
    }

    RNFrame frame = RNFrameFactory.buildFrame(mImageData, mWidth, mHeight, mRotation);
    return mBarcodeDetector.detect(frame);
  }

  @Override
  protected void onPostExecute(SparseArray<Barcode> barcodes) {
    super.onPostExecute(barcodes);

    if (barcodes == null) {
      mDelegate.onBarcodeDetectionError(mBarcodeDetector);
    } else {
      if (barcodes.size() > 0) {
        mDelegate.onBarcodesDetected(barcodes, mWidth, mHeight, mRotation);
      }
      mDelegate.onBarcodeDetectingTaskCompleted();
    }
  }

What should we do with Dynamsoft Barcode Reader?

For Dynamsoft Barcode Reader, the detection method and the returned result type are different. Create DynamsoftBarcodeDetectorAsyncTaskDelegate.java:

package org.reactnative.camera.tasks;

import com.dynamsoft.barcode.TextResult;

public interface DynamsoftBarcodeDetectorAsyncTaskDelegate {
    void onDynamsoftBarCodeDetected(TextResult[] barcodes, int width, int height);
    void onDynamsoftBarCodeDetectingTaskCompleted();
}

And DynamsoftBarcodeDetectorAsyncTask.java:

@Override
  protected TextResult[] doInBackground(Void... ignored) {
    if (isCancelled() || mDelegate == null) {
      return null;
    }

    TextResult[] results = null;

    try {
        mBarcodeReader.decodeBuffer(mImageData, mWidth, mHeight, mWidth, EnumImagePixelFormat.IPF_NV21, "");
        results = mBarcodeReader.getAllTextResults();
    } catch (Exception e) {
        e.printStackTrace();
    }

    return results;
  }

  @Override
  protected void onPostExecute(TextResult[] results) {
    super.onPostExecute(results);
    if (results != null) {
      mDelegate.onDynamsoftBarCodeDetected(results, mWidth, mHeight);
    }
    mDelegate.onDynamsoftBarCodeDetectingTaskCompleted();
  }

Define and use the event onDynamsoftVisionBarcodesDetected:

import React, { Component } from 'react';
import {StyleSheet, Text, View, Dimensions } from 'react-native';

import { RNCamera } from 'react-native-camera';

export default class App extends Component {
	constructor() {
		super();
		this.state = {
			barcodeResult: 'No barcode detected.'
		};
	}

	render() {
		return (
			<RNCamera
				ref={(ref) => {
					this.camera = ref;
				}}
				style={styles.preview}
				type={RNCamera.Constants.Type.back}
				flashMode={RNCamera.Constants.FlashMode.on}
				permissionDialogTitle={'Permission to use camera'}
        permissionDialogMessage={'We need your permission to use your camera phone'}
        onDynamsoftVisionBarcodesDetected={({ barcodes }) => {

				  if (barcodes) {
            if (barcodes.length == 0) {
              this.setState({barcodeResult: 'No barcode detected.'})
            }
            else {
              let text = '';
              for (let i in barcodes) {
                let type = barcodes[i]['type'];
                let data = barcodes[i]['data'];
                text += 'Type: ' + type + ', Value: ' + data;
              }
              this.setState({barcodeResult: text})
            }
				  }
				  else {
				    this.setState({barcodeResult: 'No barcode detected.'})
				  }

        }}
			>
				<View style={styles.textBg}>
					<Text style={styles.scanText}>{this.state.barcodeResult}</Text>
				</View>
			</RNCamera>
		);
	}
}

const deviceHeight = Dimensions.get('window').height;
const deviceWidth = Dimensions.get('window').width;
const styles = StyleSheet.create({
	textBg: {
		width: deviceWidth,
		height: 100,
		marginTop: deviceHeight - 100
	},
	preview: {
		flex: 1,
		alignItems: 'center',
		justifyContent: 'space-between'
	},
	scanText: {
		color: 'white',
    textAlign: 'center',
    fontSize: 20
	}
});

How to run the app?

When I tried to install the module from the local path, I got the error:

error: bundling failed: Error: Unable to resolve module `react-native-camera` from `F:\react-native-camera\Example\App.js`: Module `react-native-camera` does not exist in the Haste module map

node npm haste module map

module map

So far, I have not found any workaround for installing Node.js module locally. The only solution is to install react-native-camera to node_modules first:

npm install react-native-camera –save

Then, overwrite the module with my code.

Run the app:

react native camera with Dynamsoft Barcode Reader

Source Code

https://github.com/yushulx/react-native-camera

The post How to Integrate Dynamsoft Barcode Reader into React Native Camera appeared first on Code Pool.

How to Use Node RED with Barcode Module on Windows 10

$
0
0

Node-RED is a flow-based programming tool built-on Node.js. It provides a browser-based editor that helps users to create awesome applications by wiring different nodes. This article shares my experience of building a barcode node with Dynamsoft Barcode Reader on Windows.

Installing and Running Node RED on Windows 10

Install Node-RED:

sudo npm install -g --unsafe-perm node-red

On Windows, the default installation directory is %userprofile%\ .node-red.

Run Node-RED:

node-red

It failed when I started Node-RED for the first time. Here is the error message:

Welcome to Node-RED
===================

5 Nov 14:29:12 - [info] Node-RED version: v0.19.5
5 Nov 14:29:12 - [info] Node.js  version: v8.11.3
5 Nov 14:29:12 - [info] Windows_NT 10.0.17763 x64 LE
5 Nov 14:29:13 - [info] Loading palette nodes
5 Nov 14:29:14 - [warn] rpi-gpio : Raspberry Pi specific node set inactive
5 Nov 14:29:15 - [warn] ------------------------------------------------------
5 Nov 14:29:16 - [warn] [node-red/tail] Not currently supported on Windows.
5 Nov 14:29:16 - [warn] ------------------------------------------------------
5 Nov 14:29:16 - [info] Settings file  : \Users\xiao\.node-red\settings.js
5 Nov 14:29:16 - [info] Context store  : 'default' [module=memory]
5 Nov 14:29:16 - [info] User directory : \Users\xiao\.node-red
5 Nov 14:29:16 - [warn] Projects disabled : editorTheme.projects.enabled=false
5 Nov 14:29:16 - [info] Flows file     : \Users\xiao\.node-red\flows_DESKTOP-3PCHU10.json
5 Nov 14:29:16 - [info] Creating new flow file
5 Nov 14:29:16 - [info] Starting flows
5 Nov 14:29:16 - [info] Started flows
5 Nov 14:29:16 - [error] Uncaught Exception:
5 Nov 14:29:16 - [error] Error: listen EACCES 0.0.0.0:1880
    at Object._errnoException (util.js:992:11)
    at _exceptionWithHostPort (util.js:1014:20)
    at Server.setupListenHandle [as _listen2] (net.js:1338:19)
    at listenInCluster (net.js:1396:12)
    at doListen (net.js:1505:7)
    at _combinedTickCallback (internal/process/next_tick.js:141:11)
at process._tickCallback (internal/process/next_tick.js:180:9)

It seems something wrong with the default port 1880. We can use Resource Monitor to check the port usage.

windows resource manager

I did not find 1880 in the port list. I tried a port that is in use and got a different error message:

5 Nov 14:40:00 - [info] Node-RED version: v0.19.5
5 Nov 14:40:00 - [info] Node.js  version: v8.11.3
5 Nov 14:40:00 - [info] Windows_NT 10.0.17763 x64 LE
5 Nov 14:40:01 - [info] Loading palette nodes
5 Nov 14:40:01 - [warn] rpi-gpio : Raspberry Pi specific node set inactive
5 Nov 14:40:03 - [warn] ------------------------------------------------------
5 Nov 14:40:03 - [warn] [node-red/tail] Not currently supported on Windows.
5 Nov 14:40:03 - [warn] ------------------------------------------------------
5 Nov 14:40:03 - [info] Settings file  : \Users\xiao\.node-red\settings.js
5 Nov 14:40:03 - [info] Context store  : 'default' [module=memory]
5 Nov 14:40:03 - [info] User directory : \Users\xiao\.node-red
5 Nov 14:40:03 - [warn] Projects disabled : editorTheme.projects.enabled=false
5 Nov 14:40:03 - [info] Flows file     : \Users\xiao\.node-red\flows_DESKTOP-3PCHU10.json
5 Nov 14:40:03 - [info] Creating new flow file
5 Nov 14:40:03 - [info] Starting flows
5 Nov 14:40:03 - [info] Started flows
5 Nov 14:40:03 - [error] Unable to listen on http://127.0.0.1:1551/
5 Nov 14:40:03 - [error] Error: port in use

The workaround is to change the port number in %userprofile%\.node-red\settings.js. For example, we can change the default port number to 18800 and then it will work:

node red

Building Barcode Node

Let’s create a barcode node with Dynamsoft Barcode Reader.

Use npm command to initialize a Node RED project:

npm init barcode

Add the node-red section to package.json:

"node-red": {
    "nodes": {
      "barcode": "barcode.js"
    }
  },

Install Dynamsoft Barcode Reader:

npm install dbr --save

Create barcode.js:

module.exports = function(RED) {
  var dbr = require('dbr');
  var barcodeTypes = 0x3FF | 0x2000000 | 0x4000000 | 0x8000000 | 0x10000000; // 1D, PDF417, QRCODE, DataMatrix, Aztec Code

  function BarcodeNode(config) {
    RED.nodes.createNode(this, config);
    this.license = config.license;
    this.template = config.template;
    var node = this;
    node.on('input', function(msg) {
      if (msg.filename) {
        dbr.initLicense(node.license);
        dbr.decodeFileAsync(msg.filename, barcodeTypes, function(err, results) {
          msg.payload = results;
          node.send(msg);
        }, node.template);
      } else {
        msg.payload = msg.payload.toLowerCase();
        node.send(msg);
      }
    });
  }
  RED.nodes.registerType('barcode', BarcodeNode);
}

When receiving the input event, we can call the barcode decoding method by setting license and parameter templates.

Create barcode.html:

<script type="text/javascript">
    RED.nodes.registerType('barcode',{
        category: 'Dynamsoft',
        color: '#a6bbcf',
        defaults: {
            name: {value:""},
            license: {value:""},
            template: {value: ""}
        },
        inputs:1,
        outputs:1,
        icon: "function.png",
        label: function() {
            return this.name||"barcode";
        }
    });
</script>

<script type="text/x-red" data-template-name="barcode">
    <div class="form-row">
        <label for="node-input-name"><i class="icon-tag"></i> Name</label>
        <input type="text" id="node-input-name" placeholder="Barcode Reader">
    </div>
    <div class="form-row">
        <label for="node-input-license"><i class="icon-tag"></i> License</label>
        <input type="text" id="node-input-license" placeholder="https://www.dynamsoft.com/CustomerPortal/Portal/Triallicense.aspx">
    </div>
    <div class="form-row">
        <label for="node-input-template"><i class="icon-tag"></i> Template</label>
        <input type="text" id="node-input-template" placeholder="https://www.dynamsoft.com/help/Barcode-Reader/devguide/Template/TemplateSettingsList.html">
    </div>
</script>

<script type="text/x-red" data-help-name="barcode">
    <p>A simple node that read barcodes from image files.</p>
</script>

Install and test the project:

cd %userprofile%\.node-red
npm install <node-red barcode project>
node-red

Open http://127.0.0.1:18800/ in your web browser. Add inject nodefile nodebarcode node and debug node. You can set the image path in the file node:

node red debug

Click barcode node to set a valid license and barcode parameter template:

node red barcode license

Here is an example of a template:

{
  "ImageParameter": {
    "Name": "Custom_143301_827",
    "BarcodeFormatIds": [
      "OneD"
    ]
  }
}

If you do not set a template, the default template will be used.

Run the app:

node red barcode results

If there is something wrong with dbr.node(compatibility issue caused by Node.js version), you can use the source code to build it by yourself.

It everything works well, we can publish the module:

cd <node red barcode project>
npm publish

Use the module:

cd %userprofile%\.node-red
npm install node-red-contrib-barcode --save

References

https://nodered.org/docs/

Source Code

https://github.com/yushulx/node-red-contrib-barcode

The post How to Use Node RED with Barcode Module on Windows 10 appeared first on Code Pool.

Building UWP Barcode Reader with C++/WinRT and JavaScript

$
0
0

This article shows how to use Dynamsoft C++ barcode reader SDK to create a Window runtime component, as well as how to use the WinRT component and JavaScript to build a UWP app on Windows 10.

Prerequisites

Building WinRT Component with C++ DLLs

Create a new Windows Runtime Component project by using the C++ template.

windows runtime component

Open the properties of the Windows Runtime Component project to add the path of header files and library files, as well as add the input dependency.

dynamsoft barcode reader header files

dynamsoft barcode reader lib directory

dynamsoft barcode reader libs

According to the dependent libraries, change the build platform from Any CPU to x86 or x64.

anycpu x86 x64

Rename default class to BarcodeReader and add a new method DecodeFileStream().

BarcodeReader.h:

#pragma once
#include "DynamsoftBarcodeReader.h"

#include <wrl.h>
#include <robuffer.h>

using namespace Windows::Storage;
using namespace Windows::Storage::Streams;
using namespace Microsoft::WRL;
using namespace Platform;

namespace Dynamsoft
{
    public ref class BarcodeReader sealed
    {
    public:
        BarcodeReader();
		Array<String^>^ DecodeFileStream(IBuffer^ pixelBuffer);
    };
}

BarcodeReader.cpp:

#include "pch.h"
#include "BarcodeReader.h"

using namespace Dynamsoft;
using namespace Platform;

BarcodeReader::BarcodeReader()
{
}

byte* GetPointerToPixelData(IBuffer^ pixelBuffer, unsigned int *length)
{
	if (length != nullptr)
	{
		*length = pixelBuffer->Length;
	}
	// Query the IBufferByteAccess interface.
	ComPtr<IBufferByteAccess> bufferByteAccess;
	reinterpret_cast<IInspectable*>(pixelBuffer)->QueryInterface(IID_PPV_ARGS(&bufferByteAccess));

	// Retrieve the buffer data.
	byte* pixels = nullptr;
	bufferByteAccess->Buffer(&pixels);
	return pixels;
}

Array<String^>^ BarcodeReader::DecodeFileStream(IBuffer ^ pixelBuffer)
{
	CBarcodeReader reader;
	reader.InitLicense("t0068NQAAACqUjZa21C+W7fRdPkf2FRFRr+QpfVC2tDsl/8t25TzYCNxl5s0OkuwFgEMGNfN95Z0HYQ55ROi1px9JqVAP7/c=");
	unsigned int length = 0;
	byte* buffer = GetPointerToPixelData(pixelBuffer, &length);
	int ret = reader.DecodeFileInMemory(buffer, length, "");
	STextResultArray *paryResult = NULL;
	reader.GetAllTextResults(&paryResult);

	Array<String^>^ results = ref new Array<String^>(paryResult->nResultsCount);
	for (int i = 0; i < paryResult->nResultsCount; ++i) {
		std::string s_str = std::string(paryResult->ppResults[i]->pszBarcodeText);
		std::wstring wid_str = std::wstring(s_str.begin(), s_str.end());
		const wchar_t* w_char = wid_str.c_str();
		results->set(i, ref new String(w_char));
	}

	return results;
}

Build the project to generate Dynamsoft.winmd and Dynamsoft.dll.

Building a Simple UWP Barcode Reader in JavaScript

Create a new UWP project by using the JavaScript template.

UWP barcode

Add the created Windows Runtime Component project as a reference.

project reference

Add a <button> and a <div> to index.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>UWPBarcode</title>
    <link href="css/default.css" rel="stylesheet" />
</head>
<body>
    <h1>Dynamsoft Barcode Reader</h1>
    <button type="button" id="fileinput">Load an image</button>
    <div id="results"></div>
    <script src="js/main.js"></script>
</body>
</html>

Use file picker to load an image from local disk, and call the native API to decode barcodes in main.js:

var reader = new Dynamsoft.BarcodeReader();
function readBarcode() {
    var picker = new Windows.Storage.Pickers.FileOpenPicker();
    picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
    picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
    picker.fileTypeFilter.append(".jpg");
    picker.fileTypeFilter.append(".jpeg");
    picker.fileTypeFilter.append(".png");

    picker.pickSingleFileAsync().then(function(file) {
        if (file != null) {
            Windows.Storage.FileIO.readBufferAsync(file).then(function (buffer) {
                let result = reader.decodeFileStream(buffer);
                document.getElementById('results').innerHTML = JSON.stringify(result);
            }
            );
        }
        else {
            document.getElementById('results').innerHTML = "Operation cancelled.";
        }
    });

}

document.getElementById('fileinput').addEventListener('click', readBarcode, false);

Add dependent native DLLs to the project and set “Copy always” as the build action.

dll copy

Build and run the app.

UWP winrt barcode reader

References

Source Code

https://github.com/yushulx/winrt-javascript-uwp

The post Building UWP Barcode Reader with C++/WinRT and JavaScript appeared first on Code Pool.

Building Cordova Plugin with Windows Runtime Component

$
0
0

In my last article, I shared how to build WinRT component with Dynamsoft Barcode Reader C++ SDK. This article shows how to use the generated Dynamsoft.dll and Dynamsoft.winmd files in a Cordova plugin project for building Windows 10 apps.

Installation

My First Windows App with Cordova

Run VS 2017 command line tool.

Install Cordova:

npm install -g cordova

Create a new project:

cordova create test com.dynamsoft.test Test

Add windows platform:

cordova platform add windows

Build the app:

cordova build windows

You may see the following error:

c:\Prog
ram Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\VisualStudio\v15.0\JavaScript\Microsoft.Visual
Studio.WJProject.Default.props" was not found.

cordova windows build error

The error means you don’t have JavaScript-relevant SDK and tools installed. Open Visual Studio installer to check it.

vs2017 cordova

Creating Cordova Plugin with WinRT and Native DLLs

We can follow the official tutorial to create a basic Cordova plugin.

Here is mine:

cordova windows plugin

Note: we can use ildasm.exe, which is located under C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.2 Tools, to view .winmd files.

The package.json file is created by NPM command:

{
  "name": "cordova-windows-barcode",
  "version": "0.0.1",
  "description": "Cordova Windows barcode",
  "cordova": {
    "id": "cordova-windows-barcode",
    "platforms": [
      "windows"
    ]
  },
  "keywords": [
    "cordova",
    "barcode",
    "ecosystem:cordova",
    "cordova-windows"
  ],
  "author": "Dynamsoft",
  "license": "MIT"
}

Configure JavaScript modules, C++/WinRT component, and native DLLs in plugin.xml:

<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" id="barcode" version="0.1.0">

    <js-module src="www/barcode.js" name="Barcode">
        <clobbers target="cordova.plugins.barcode" />
    </js-module>

    <!-- windows -->
    <platform name="windows">
        <js-module src="src/windows/barcodeProxy.js" name="BarcodeProxy">
            <merges target="" />
        </js-module>
        <resource-file src="src/windows/libs/x86/DynamsoftBarcodeReaderx86.dll" target="DynamsoftBarcodeReaderx86.dll" arch="x86" reference="true" />
        <resource-file src="src/windows/libs/x86/DynamicPdf.dll" target="DynamicPdf.dll" arch="x86" reference="true" />
        <resource-file src="src/windows/libs/x86/vcomp110.dll" target="vcomp110.dll" arch="x86" reference="true" />

        <framework src="src/windows/libs/x86/BarcodeComponent.winmd" target-dir="x86" arch="x86" custom="true"/>
        <framework src="src/windows/libs/x86/Dynamsoft.winmd" target-dir="x86" arch="x86" custom="true" implementation="src/windows/libs/x86/Dynamsoft.dll"/>
    </platform>
</plugin>

To communicate with the native platform, call cordova.exec in barcode.js:

function BarcodeReader() {
}

BarcodeReader.prototype.decodeFileStream = function(successCallback, errorCallback) {
    cordova.exec(successCallback, errorCallback, "Barcode", "decodeFileStream");
};

var barcodeReader = new BarcodeReader();

module.exports = barcodeReader;

In barcodeProxy.js, use the file picker to load image files and call decodeFileStream() to read barcodes:

cordova.commandProxy.add('Barcode', {
  decodeFileStream: function(successCallback, errorCallback) {
    var picker = new Windows.Storage.Pickers.FileOpenPicker();
    picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
    picker.SuggestedStartLocation =
        Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
    picker.fileTypeFilter.append('.jpg');
    picker.fileTypeFilter.append('.jpeg');
    picker.fileTypeFilter.append('.png');

    picker.pickSingleFileAsync().then(function(file) {
      if (file != null) {
        Windows.Storage.FileIO.readBufferAsync(file).then(function(buffer) {
            let reader = new Dynamsoft.BarcodeReader();
            let result = reader.decodeFileStream(buffer);
            successCallback(result);
        });
      } else {
        errorCallback('Operation cancelled.');
      }
    });
  }
});

Add the plugin to your project:

cordova plugin add <local plugin path>

Specify the arch(x86 or x64) to run the app:

cordova run windows -- --arch="x86"

Unfortunately, the app fails to work when calling the native API. I debugged the app in Visual Studio, and got the exception:

Exception is about to be caught by JavaScript library code at line 15, column 13 in ms-appx-web://com.dynamsoft.test/www/plugins/barcode/src/windows/barcodeProxy.js
0x8007007e - JavaScript runtime error: The specified module could not be found.

cordova module not found

It seems to be a bug because the module is out there. After I created an empty .winmd file built with the C# template and added it as a reference, the exception was gone.

cordova windows barcode reader

References

Source Code

https://github.com/yushulx/cordova-windows-barcode

The post Building Cordova Plugin with Windows Runtime Component appeared first on Code Pool.

How to Use Dynamsoft JavaScript Barcode SDK in Angular

$
0
0

Dynamsoft JavaScript barcode SDK is built based on WebAssembly. In this article, I will illustrate how to build a simple web barcode reader app by using Dynamsoft JavaScript barcode SDK and Angular.

Using JavaScript Barcode SDK in an Angular CLI Project

Create an Angular CLI project

Install Angular CLI:

npm install -g @angular/cli

Create a new project:

ng new barcode-reader

Build and run the app:

ng serve --open

Use Dynamsoft JavaScript barcode library

Open src/index.html to add <script> elements. Declare ‘dynamsoft’ as a global variable:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>BarcodeReader</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <script id="script"></script>
  <script >var dynamsoft = self.dynamsoft || {};
  </script>
</head>
<body>
  <app-root></app-root>
</body>
</html>

Add an HTMLImageElement (loading animation), an HTMLInputElement (file picker) and an HTMLDivElement (text display) to src/app/app.component.html:

<div style="text-align:left">
  <h1>
    Welcome to {{ title }}!
  </h1>
  <img src="assets/loading.gif" style="margin-top:10px" id="anim-loading">
  <div>
    <input id="uploadImage" type="file" accept="image/bmp,image/jpeg,image/png,image/gif" (input)="readBarcode()">
  </div>
  <div><b>Barcode result:</b> {{results}}</div>
</div>
<router-outlet></router-outlet>

In src/app/app.component.ts, add a constructor() to initialize ‘dynamsoft’ and dynamically load the Dynamsoft JavaScript barcode library:

export class AppComponent {
    title = 'Dynamsoft Barcode Reader';
    results = '';
    reader;

    constructor() {
        const env = this;
        dynamsoft.dbrEnv = dynamsoft.dbrEnv || {};
        dynamsoft.dbrEnv.resourcesPath = 'https://demo.dynamsoft.com/dbr_wasm/js';
        //https://www.dynamsoft.com/CustomerPortal/Portal/TrialLicense.aspx
        dynamsoft.dbrEnv.licenseKey =
            't0068NQAAADAG7KITlB55pjkzxD1rnTRhcZ/KCqVoXp6vWXmjRUbhvkCl58F+mqFnhIo1Oul/qB0moA8nA1erzTPYsb4FVLk=';
        dynamsoft.dbrEnv.bUseWorker = true;
        dynamsoft.dbrEnv.onAutoLoadWasmSuccess = function() {
            env.reader = new dynamsoft.BarcodeReader();
            document.getElementById('anim-loading').style.display = 'none';
        };
        dynamsoft.dbrEnv.onAutoLoadWasmError = function(ex) {
            alert(ex);
        };

        let bMobileSafari =
            /Safari/.test(navigator.userAgent) &&
            /iPhone/.test(navigator.userAgent) &&
            !/Chrome/.test(navigator.userAgent);

        let script = document.getElementById('script');
        if (!bMobileSafari) {
            script.src = 'https://demo.dynamsoft.com/dbr_wasm/js/dbr-6.3.0.2.min.js';
        } else {
            // bMobileSafari
            // js for mobile(safari especially): smaller, compile quicker, need less memory, but not that stable
            script.src = 'https://demo.dynamsoft.com/dbr_wasm/js/dbr-6.3.0.2.mobile.min.js';
        }
    }
 }

Create a function readBarcode() for binding the HTMLInputElement:

readBarcode(): void {
        const env = this;
        let image = document.getElementById('uploadImage').files[0];
        if (!image) {
            alert('Please add an image');
            return;
        }
        this.reader
            .decodeFileInMemory(image)
            .then(function(results) {
                var txts = [];
                for (var i = 0; i < results.length; ++i) {
                    txts.push(results[i].BarcodeText);
                }
                env.results = JSON.stringify(txts);
            })
            .catch((ex) => {
                alert(ex);
            });
    }

That’s it. I can now successfully run the app:

Angular WebAssembly barcode

Fix Angular CLI errors

Although the web barcode reader runs well, there are some errors displayed in the command line tool:

angular error

Seeing so many errors makes me uncomfortable, and thus I have to fix them.

‘dynamsoft’ is a global variable which is invisible in app.component.ts. We can declare it as follows:

import { Component } from '@angular/core';

declare var dynamsoft: any;

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: [ './app.component.css' ]
})

To fix the property error, we can cast the corresponding HTML Elements with specific types:

if (!bMobileSafari) {
            (<HTMLScriptElement >script).src = 'https://demo.dynamsoft.com/dbr_wasm/js/dbr-6.3.0.2.min.js';
        } else {
            // bMobileSafari
            // js for mobile(safari especially): smaller, compile quicker, need less memory, but not that stable
            (<HTMLScriptElement >script).src = 'https://demo.dynamsoft.com/dbr_wasm/js/dbr-6.3.0.2.mobile.min.js';
        }
let image = (<HTMLInputElement>document.getElementById('uploadImage')).files[0];

Source Code

https://github.com/dynamsoft-dbr/javascript-barcode/tree/master/examples/angular

The post How to Use Dynamsoft JavaScript Barcode SDK in Angular appeared first on Code Pool.

How to Use JavaScript Barcode SDK in AngularDart Project

$
0
0

AngularDart, similar to Angular built with TypeScript, is a web app framework written in Dartlang. It finally compiles to JavaScript.  In this article, I will share how to use Dynamsoft JavaScript Barcode SDK to create a simple web barcode reader app using AngularDart on Windows 10.

Download and Installation

  • Dart SDK
  • Webdev and Stagehand:
    pub global activate webdev
    pub global activate stagehand

Building Web Barcode Reader in AngularDart

Create a new project:

mkdir barcode
cd barcode
stagehand web-angular
pub get

Here is the project view in Visual Studio Code.

AngularDart project

By default, the template contains a to-do list component. It is useless, just delete it. After that, clean up the project:

  1. Open lib/app_component.html to delete <todo-list></todo-list>.
  2. In lib/app_component.dart, remove import ‘src/todo_list/todo_list_component.dart’ and directives: [TodoListComponent].

It is time to write my code. Open web/index.html to include the JS barcode library and add the initialization code:

<!DOCTYPE html>
<html>
  <head>
    <title>barcode</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="styles.css">
    <link rel="icon" type="image/png" href="favicon.png">
    <img src="loading.gif" style="margin-top:10px" id="anim-loading">
    <script src="https://demo.dynamsoft.com/dbr_wasm/js/dbr-6.4.1.0.min.js"></script>
    <script defer src="main.dart.js"></script>
    <script>
        dynamsoft.dbrEnv = dynamsoft.dbrEnv || {};
        dynamsoft.dbrEnv.resourcesPath = 'https://demo.dynamsoft.com/dbr_wasm/js';
        //https://www.dynamsoft.com/CustomerPortal/Portal/TrialLicense.aspx
        dynamsoft.dbrEnv.licenseKey =
          't0068NQAAAJUlQ1oDc6zPWxOAQWn7kD9EGtgZFIqK/k3ULJC5ccG9Xe/lpVOxod82bm6nXxqQXUpC1zjRXU514mWw9XLE1JM=';
        dynamsoft.dbrEnv.bUseWorker = false;
        dynamsoft.dbrEnv.onAutoLoadWasmSuccess = function() {
          document.getElementById('anim-loading').style.display = 'none';
        };
        dynamsoft.dbrEnv.onAutoLoadWasmError = function(ex) {
          alert(ex);
        };
    </script>
  </head>
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

Add an HTMLInputElement and an HTMLDivElement to lib/app_component.html:

<h1>{{title}}</h1>
<div>
    <input id="uploadImage" type="file" accept="image/bmp,image/jpeg,image/png,image/gif" (input)="readBarcode()">
</div>
<div><b>Barcode result:</b> <span id='barcodeResults'>{{results}}</span></div>

Now let’s do some tricky things in lib/app_component.dart.

To interop JavaScript with Dart, we can import ‘package:js/js.dart’:

@JS()
library app_component;

import 'package:js/js.dart';

To make the package work, add dependency js: ^0.6.0 in pubspec.yaml:

dependencies:
  angular: ^5.1.0
  angular_components: ^0.10.1
  js: ^0.6.0

Declare the JavaScript barcode class and the decoding method:

import 'dart:js';
import 'dart:html';
import 'dart:convert';

@JS("dynamsoft.BarcodeReader")
class DynamsoftBarcodeReader {
  external factory DynamsoftBarcodeReader();
  external Promise<JsArray> decodeFileInMemory(File file);
}

Initialize the object:

class AppComponent implements OnInit {
  
  final title = 'Angular Dart - Barcode Reader';
  String results = '';
  DynamsoftBarcodeReader reader;

  void ngOnInit() async {
    results = '';
    reader = new DynamsoftBarcodeReader();
  }
}

Create a readBarcode() function binding with the HTMLInputElement:

void readBarcode() {
    InputElement input = document.querySelector('#uploadImage');
    FileList files = input.files;
    File file = files.item(0);

    if (reader != null) {
      reader.decodeFileInMemory(file).then(
        allowInterop(getResults)
      );
    } else {
      results = file.name;
    }
  }

The decodeFileInMemory method returns a Promise object, so we need to declare it as follows:

class Promise<T> {
  external Promise then(Function(T result));
}

The getResults() is a callback function for showing results:

void getResults(JsArray barcodes) {
    int len = barcodes.length;
    var json = jsonDecode(stringify(barcodes));
    var tmp = '';
    for (int i = 0; i < len; i++) {
      tmp += json[i]['BarcodeText'] + '; ';
    }
    
    SpanElement spanElement= document.querySelector('#barcodeResults');
    spanElement.text = tmp;
  }

Run the app:

webdev serve

If the port is unavailable, kill the relevant process:

netstat -aon | findstr 8080
taskkill /f /pid <ProcessID>

AngularDart barcode reader

Source Code

https://github.com/dynamsoft-dbr/javascript-barcode/tree/master/examples/angular-dart

The post How to Use JavaScript Barcode SDK in AngularDart Project appeared first on Code Pool.

How to Build Web Barcode Apps with React and WebAssembly

$
0
0

Dynamsoft JavaScript barcode SDK is built based on WebAssembly, which provides high performance for reading barcodes in web apps. This tutorial aims to demonstrate how to quickly create a simple web barcode reader by using React and Dynamsoft JavaScript barcode SDK.

Download

Node.js

A Simple Web Barcode Reader

Create a new react app:

npx create-react-app react-wasm-barcode
cd react-wasm-barcode

Load and initialize the JavaScript barcode library in public/index.html:

<img src="loading.gif" style="margin-top:10px" id="anim-loading">
    <script src="https://demo.dynamsoft.com/dbr_wasm/js/dbr-6.4.1.1.min.js"></script>
    <script>
      dynamsoft.dbrEnv.resourcesPath = 'https://demo.dynamsoft.com/dbr_wasm/js';
      dynamsoft.dbrEnv.onAutoLoadWasmSuccess = function () {
        window.reader = new dynamsoft.BarcodeReader();
        document.getElementById('anim-loading').style.display = 'none';
      };
      dynamsoft.dbrEnv.onAutoLoadWasmError = function (ex) {
        document.getElementById('anim-loading').style.display = 'none';
        alert('Fail to load the wasm file.');
      };

      //https://www.dynamsoft.com/CustomerPortal/Portal/TrialLicense.aspx
      dynamsoft.dbrEnv.licenseKey = "<Your Barcode License>";
</script>

If you do not have a valid license, you can register a Dynamsoft account and get a 30-day free trial license. To make the barcode reader globally accessible, assign the object to window.reader.

Create a barcode component in Barcode.js:

import React, { Component }from 'react';
export class Barcode extends Component {
    onChanged() {
        let image = document.getElementById('uploadImage').files[0];
		if (!image) {
			alert('Please add an image');
			return;
		}
        window.reader.decodeFileInMemory(image).then(function(results){
            var txts = [];
            for(var i=0;i<results.length;++i){
                txts.push(results[i].BarcodeText);
            }
            alert(txts.join("\n"));
        }).catch(ex => {
            alert('error:' + (ex.message || ex));
        });
    }
  
    render() {
      return (
        <div>
          <input id="uploadImage" type="file" accept="image/bmp,image/jpeg,image/png,image/gif" onChange={this.onChanged}/>
        </div>
      );
    }
  }

Use the Input element to load an image and write barcode detection code in the onChanged() function.

Import the barcode component to App.js:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import {Barcode} from './Barcode';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <Barcode/>
        </header>
      </div>
    );
  }
}

export default App;

Run the app:

yarn start

Open localhost:3000 in your web browser to run the demo:

The post How to Build Web Barcode Apps with React and WebAssembly appeared first on Code Pool.


How to Build Python Barcode Apps with Qt on Windows

$
0
0

Qt for Python enables developers to quickly create GUI apps on Windows, Linux and macOS with one codebase. In this article, I will share how to build a Python barcode reader with Qt on Windows. Since Dynamsoft Barcode Reader SDK is also cross-platform, it is easy for you to reuse the sample code on Linux and macOS.

Installing Qt for Python on Windows

To install Qt for Python on Windows, you can either download a .whl file or run the command:

 pip install pyside2

When using Python 3.6, I got following error message:

Error:
Traceback (most recent call last):
  File "test2.py", line 3, in <module>
    from PySide2.QtWidgets import (QApplication, QLabel, QPushButton, QVBoxLayout, QWidget)
ImportError: DLL load failed: The specified procedure could not be found.

My workaround is to install Python 3.7 instead.

Dynamsoft Barcode Reader

A Simple Python Barcode Reader with Windows GUI

Qt designer

If you feel inconvenient to build UI programmatically, you can use Qt designer which is located at Python37\Lib\site-packages\PySide2\designer.exe.

qt designer

After designing the UI by simply dragging the widgets, you can save the project to a *.ui file.

Next, convert the *.ui file to Python code with E:\Programs\Python\Python37\Scripts\pyside2-uic.exe:

pyside2-uic -x *.ui -o ui.py

Python barcode reader with Windows UI elements

We can quickly set up an app skeleton by reading the Qt for Python homepage.

My UI contains a button, a label, and a text area:

  • Button: pop up a system dialog to load image files from local disks.
  • Label: display the loaded images.
  • Text area: show barcode results.

Here is the code snippet:

import sys
from PySide2.QtGui import QPixmap

from PySide2.QtWidgets import QApplication, QLabel, QPushButton, QVBoxLayout, QWidget, QFileDialog, QTextEdit, QSizePolicy
from PySide2.QtCore import Slot, Qt, QStringListModel, QSize

import dbr
import os

class UI_Window(QWidget):

    def __init__(self):
        QWidget.__init__(self)

        # The default barcode image.
        dir_path = os.path.dirname(os.path.realpath(__file__))
        filename = os.path.join(dir_path, 'image.tif')

        # Create a layout.
        layout = QVBoxLayout()

        # Add a button
        self.btn = QPushButton("Load an image")
        self.btn.clicked.connect(self.pickFile)
        layout.addWidget(self.btn)

        # Add a label
        self.label = QLabel()
        self.label.setFixedSize(640, 640)
        pixmap = self.resizeImage(filename)
        self.label.setPixmap(pixmap)
        layout.addWidget(self.label)

        # Add a text area
        self.results = QTextEdit()
        self.readBarcode(filename)
        layout.addWidget(self.results)

        # Set the layout
        self.setLayout(layout)
        self.setWindowTitle("Dynamsoft Barcode Reader")
        self.setFixedSize(800, 800)

Connect the button to a click event:

def pickFile(self):
        # Load an image file.
        filename = QFileDialog.getOpenFileName(self, 'Open file',
                                               'E:\\Program Files (x86)\\Dynamsoft\\Barcode Reader 6.4.1\\Images', "Barcode images (*)")
        # Show barcode images
        pixmap = self.resizeImage(filename[0])
        self.label.setPixmap(pixmap)

        # Read barcodes
        self.readBarcode(filename[0])

Scale the loaded image to fit into the label:

def resizeImage(self, filename):
        pixmap = QPixmap(filename)
        lwidth = self.label.maximumWidth()
        pwidth = pixmap.width()
        lheight = self.label.maximumHeight()
        pheight = pixmap.height()

        wratio = pwidth * 1.0 / lwidth
        hratio = pheight * 1.0 / lheight

        if pwidth > lwidth or pheight > lheight:
            if wratio > hratio:
                lheight = pheight / wratio
            else:
                lwidth = pwidth / hratio

            scaled_pixmap = pixmap.scaled(lwidth, lheight)
            return scaled_pixmap
        else:
            return pixmap

Call barcode decoding method and then update the text area with the returned results:

def readBarcode(self, filename):
        dbr.initLicense("<Your License>")
        results = dbr.decodeFile(filename, 0x3FF | 0x2000000 | 0x4000000 | 0x8000000 | 0x10000000)

        out = ''
        index = 0
        for result in results:
            out += "Index: " + str(index) + "\n"
            out += "Barcode format: " + result[0] + '\n'
            out += "Barcode value: " + result[1] + '\n'
            out += '-----------------------------------\n'
            index += 1

        self.results.setText(out)

Run the app:

python barcode-reader.py

qt python barcode reader

Source Code

https://github.com/dynamsoft-dbr/python/tree/master/examples/qt

The post How to Build Python Barcode Apps with Qt on Windows appeared first on Code Pool.

How to Use Python and PyQt to Read Barcodes from Webcam

$
0
0

In my previous article, I shared how to use PyQt and Dynamsoft Barcode Reader to create a simple Windows-styled GUI app to read barcodes from image files. Now I am going to add a little bit more code to scan barcodes from the webcam video stream.

Showing Webcam Video Stream using PyQt

Usually, we can use OpenCV for Python to capture webcam frames.

pip install opencv-python

The code is pretty simple:

import cv2
vc = cv2.VideoCapture(0)
while True:
        rval, frame = vc.read()
        cv2.imshow("Camera View", frame)

When using PyQt, we cannot keep drawing the frames in an infinite loop in the main thread. Instead, we need to use a timer. I got the workaround from the StackOverflow Q&A:

def __init__(self):
        # Create a timer.
        self.timer = QTimer()
        self.timer.timeout.connect(self.nextFrameSlot)

def nextFrameSlot(self):
        rval, frame = self.vc.read()
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        image = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
        pixmap = QPixmap.fromImage(image)
        self.label.setPixmap(pixmap)

        results = dbr.decodeBuffer(frame, 0x3FF | 0x2000000 | 0x4000000 | 0x8000000 | 0x10000000)
        out = ''
        index = 0
        for result in results:
            out += "Index: " + str(index) + "\n"
            out += "Barcode format: " + result[0] + '\n'
            out += "Barcode value: " + result[1] + '\n'
            out += '-----------------------------------\n'
            index += 1

        self.results.setText(out)

In the function that triggered periodically via the timer, we can use OpenCV to capture a frame and decode the frame by calling the API of Dynamsoft Barcode Reader SDK. Note: before creating a QImage with the frame, we have to convert the color space of the frame from BRG to RGB.

Create a horizontal layout QHBoxLayout, which contains two buttons:

button_layout = QHBoxLayout()

btnCamera = QPushButton("Open camera")
btnCamera.clicked.connect(self.openCamera)
button_layout.addWidget(btnCamera)

btnCamera = QPushButton("Stop camera")
btnCamera.clicked.connect(self.stopCamera)
button_layout.addWidget(btnCamera)

layout.addLayout(button_layout)

Connect the buttons to some click events:

def openCamera(self):
        self.vc = cv2.VideoCapture(0)
        # vc.set(5, 30)  #set FPS
        self.vc.set(3, 640) #set width
        self.vc.set(4, 480) #set height

        if not self.vc.isOpened(): 
            msgBox = QMessageBox()
            msgBox.setText("Failed to open camera.")
            msgBox.exec_()
            return

        self.timer.start(1000./24)
    
def stopCamera(self):
        self.timer.stop()

Use closeEvent to pop up a confirm box for exit prompt:

def closeEvent(self, event):
    
        msg = "Close the app?"
        reply = QMessageBox.question(self, 'Message', 
                        msg, QMessageBox.Yes, QMessageBox.No)

        if reply == QMessageBox.Yes:
            event.accept()
            self.stopCamera()
        else:
            event.ignore()

Run the app:

Python barcode scanner built with PyQt and webcam

Source Code

https://github.com/dynamsoft-dbr/python/tree/master/examples/qt

The post How to Use Python and PyQt to Read Barcodes from Webcam appeared first on Code Pool.

How to Build Web Barcode Scanner Using React and Webcam

$
0
0

Someone asked me how to create a real-time web barcode scanning app with a webcam. Is it hard to implement it? I’ve written an article sharing how to integrate Dynamsoft JavaScript Barcode Reader SDK into a React project. The remaining work is to make a webcam component.  Since there is an open source project called react-webcam, we don’t need to reinvent the wheel. In this article, I will share how to build a web barcode scanner step by step.

Camera-based Web Barcode Scanning Component

Download and open react-webcam.js.

Find render() function to add a button and a canvas. We use the button to trigger barcode scan and render barcode results on the canvas:

render() {
    return (
      <div id='videoview' width={this.props.width} height={this.props.height}>
        <button onClick={this.scanBarcode}>Scan Barcodes</button>
        <video
          autoPlay
          width={this.props.width}
          height={this.props.height}
          src={this.state.src}
          muted={this.props.audio}
          className={this.props.className}
          playsInline
          style={this.props.style}
          ref={(ref) => {
            this.video = ref;
          }}
        />
        <canvas id="overlay" width={this.props.width} height={this.props.height}></canvas>
      </div>
    );
  }

To show the results on the video, we need to adjust the styles of the HTML elements. Create a react-webcam.css file:

#videoview {
    position: relative;
    width: 640px;
    height: 480px;
  }

#video {
    position: relative;
    width: 100%;
    height: 100%;
    z-index: 1
}

#overlay {
    position: absolute;
    top: 100;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 2
}

Import the CSS file in the react-webcam.js file:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import './react-webcam.css';

Create a scanBarcode() function, in which we need to get the byte array of the video frame and then call the decodeBuffer() method:

scanBarcode() {
    if (window.reader) {
      let canvas = document.createElement('canvas');
      canvas.width = this.props.width;
      canvas.height = this.props.height
      let ctx = canvas.getContext('2d');
      ctx.drawImage(this.video, 0, 0, this.props.width, this.props.height);
    
      window.reader.decodeBuffer(
        ctx.getImageData(0, 0, canvas.width, canvas.height).data,
        canvas.width,
        canvas.height,
        canvas.width * 4,
        window.dynamsoft.BarcodeReader.EnumImagePixelFormat.IPF_ARGB_8888
      )
      .then((results) => {
        this.showResults(results);
      });
    }
    
  }

How to make the window.reader initialized? In public/index.html, create the instance of the barcode reader and make it globally accessible once the wasm file is loaded:

<body>
    <img src="loading.gif" style="margin-top:10px" id="anim-loading">
    <script src="https://demo.dynamsoft.com/dbr_wasm/js/dbr-6.4.1.3.min.js"></script>
    <script>
      dynamsoft.dbrEnv.resourcesPath = 'https://demo.dynamsoft.com/dbr_wasm/js';
      dynamsoft.dbrEnv.onAutoLoadWasmSuccess = function () {
        window.reader = new dynamsoft.BarcodeReader();
        window.dynamsoft = dynamsoft;
        document.getElementById('anim-loading').style.display = 'none';
      };
      dynamsoft.dbrEnv.onAutoLoadWasmError = function (ex) {
        document.getElementById('anim-loading').style.display = 'none';
        alert('Fail to load the wasm file.');
      };
      dynamsoft.dbrEnv.bUseWorker = true;

      // Get a free trial license from https://www.dynamsoft.com/CustomerPortal/Portal/TrialLicense.aspx
      dynamsoft.dbrEnv.licenseKey = "Your Barcode SDK License"

    </script>
    <div id="root"></div>

Note: dynamsoft.dbrEnv.bUseWorker has to be true. If we do not use web worker, the main thread will be heavily blocked.

To make this work in scanBarcode(), bind it in the constructor:

constructor() {
    super();
    this.state = {
      hasUserMedia: false,
    };

    this.scanBarcode = this.scanBarcode.bind(this);
  }

The following code shows how to continuously scan and show the barcode results on the webcam video:

showResults(results) {
    let context = this.clearOverlay();
    let txts = [];
    try {
      let localization;
      for (var i = 0; i < results.length; ++i) {
        if (results[i].LocalizationResult.ExtendedResultArray[0].Confidence >= 30) {
          txts.push(results[i].BarcodeText);
          localization = results[i].LocalizationResult;
          this.drawResult(context, localization, results[i].BarcodeText);
        }
      }
      
      this.scanBarcode();
      
    } catch (e) {
      this.scanBarcode();
    }
  }

clearOverlay() {
    let context = document.getElementById('overlay').getContext('2d');
    context.clearRect(0, 0, this.props.width, this.props.height);
    context.strokeStyle = '#ff0000';
    context.lineWidth = 5;
    return context;
  }
  
drawResult(context, localization, text) {
    context.beginPath();
    context.moveTo(localization.X1, localization.Y1);
    context.lineTo(localization.X2, localization.Y2);
    context.lineTo(localization.X3, localization.Y3);
    context.lineTo(localization.X4, localization.Y4);
    context.lineTo(localization.X1, localization.Y1);
    context.stroke();
  
    context.font = '18px Verdana';
    context.fillStyle = '#ff0000';
    let x = [ localization.X1, localization.X2, localization.X3, localization.X4 ];
    let y = [ localization.Y1, localization.Y2, localization.Y3, localization.Y4 ];
    x.sort(function(a, b) {
      return a - b;
    });
    y.sort(function(a, b) {
      return b - a;
    });
    let left = x[0];
    let top = y[0];
  
    context.fillText(text, left, top + 50);
  }

Open App.js to add the React webcam component:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import {Barcode} from './Barcode';
import Webcam from './react-webcam';

class App extends Component {
  render() {
    return (
      <div className="App">
        <Barcode/>
        <Webcam />
      </div>
    );
  }
}

export default App;

Run the web barcode scanner app:

npm start

Visit localhost:3000:

react web barcode scanner with webcam

Source Code

https://github.com/dynamsoft-dbr/javascript-barcode/tree/master/examples/react-wasm-barcode

The post How to Build Web Barcode Scanner Using React and Webcam appeared first on Code Pool.

Moving Heavy Computation from Raspberry Pi to Windows PC

$
0
0

If you want to use Raspberry Pi as an economical way of detecting barcodes, you can take account for Dynamsoft Barcode Reader SDK. As a business software, Dynamsoft Barcode Reader SDK is designed for overcoming a variety of complicated scenarios with sophisticated algorithms and heavy computations. Although the SDK is flexible for customizing algorithm parameters, subject to the low-frequency CPU of Raspberry Pi, the tradeoff between recognition accuracy and detection speed is still a big challenge. In this article, I will use Socket client-server model as a substitute solution. Thanks to Sabjorn’s NumpySocket module.

 System Requirements

Python Barcode Reader Module

Install Dynamsoft Barcode Reader and follow the GitHub repository to build and install the Python barcode module.

Why do We Need the Socket Client-Server Model for Raspberry Pi

I am using the Raspberry Pi 3 Model B+:

  • Broadcom BCM2837B0, Cortex-A53 (ARMv8) 64-bit SoC @ 1.4GHz
  • 1GB LPDDR2 SDRAM

Here is the time cost of calling the barcode decoding method on Raspberry Pi. Let’s see the resolution of 640×480 first.

Raspberry Pi Python barcode reader

The average elapsed time is more than 400ms. What about the resolution of 320×240?

Raspberry Pi native barcode

It seems a little bit better but not stable. The CPU utilization may reach 100% which will freeze the process. That is why we need the Socket client-server model by which we can continuously send video frames from Raspberry Pi to a remote server and execute barcode detection tasks on the server.

How to Implement the C/S Model for Barcode Detection

Install OpenCVscipy, and pillow on Raspberry Pi:

$ sudo apt-get install libopencv-dev python-opencv python-scipy
$ python -m pip install pillow

Download NumpySocket. The Python module has already implemented the function of transferring the NumPy array. I only added two methods for sending and receiving barcode results in JSON formats:

import json
def sendJSON(self, data):
    out = json.dumps(data)

    try:
        self.connection.sendall(out)
    except Exception:
        exit()

def receiveJSON(self):
    try:
        chunk = self.socket.recv(1024)    
    except Exception:
        exit()
            
    return json.loads(chunk)

Create a pc.py file:

from numpysocket import NumpySocket
import cv2
import time
import json
import dbr

# Get the license of Dynamsoft Barcode Reader from https://www.dynamsoft.com/CustomerPortal/Portal/Triallicense.aspx
dbr.initLicense('LICENSE KEY')

npSocket = NumpySocket()
npSocket.startServer(9999)

# Receive frames for barcode detection
while(True):
    try:
        frame = npSocket.recieveNumpy()
        # cv2.imshow('PC Reader', frame)
        results = dbr.decodeBuffer(frame, 0x3FF | 0x2000000 | 0x4000000 | 0x8000000 | 0x10000000)
        out = {}
        out['results'] = results

        # Send barcode results to Raspberry Pi
        npSocket.sendJSON({'results': results})
    except:
        break
    
    # Press ESC to exit
    key = cv2.waitKey(20)
    if key == 27 or key == ord('q'):
        break

npSocket.endServer()
print('Closed')

In the infinite loop, receive the video frames from Raspberry Pi and then call barcode decoding function to get the results.

Create a rpi.py file. In this file, create a queue for storing and sharing video frames between threads:

def read_barcode():
    vc = cv2.VideoCapture(0)
    vc.set(3, 640) #set width
    vc.set(4, 480) #set height

    if not vc.isOpened():
        print('Camera is not ready.')
        return

    host_ip = '192.168.8.84' 
    npSocket = NumpySocket()
    npSocket.startClient(host_ip, 9999)

    socket_thread = SocketThread('SocketThread', npSocket)
    socket_thread.start() 

    while vc.isOpened():
        
        ret, f = vc.read()
        cv2.imshow("RPi Reader", f)
        frame = imresize(f, .5)

        key = cv2.waitKey(20)
        if key == 27 or key == ord('q'):   
            socket_thread.isRunning = False
            socket_thread.join() 
            break

        if not socket_thread.is_alive():
            break
        
        try:
            frame_queue.put_nowait(frame)
        except:
            # Clear unused frames
            try:
                while True:
                    frame_queue.get_nowait()
            except:
                pass

    frame_queue.close()
    frame_queue.join_thread()
    vc.release()

Create a worker thread for Socket connection:

class SocketThread (threading.Thread):
    def __init__(self, name, npSocket):
        threading.Thread.__init__(self)
        self.name = name
        self.npSocket = npSocket
        self.isRunning = True

    def run(self):      
        while self.isRunning:
            frame = frame_queue.get(timeout=100)

            try:
                start_time = time.time()
                self.npSocket.sendNumpy(frame)
                obj = self.npSocket.receiveJSON()
                print("--- %.2f ms seconds ---" % ((time.time() - start_time) * 1000))
                data = obj['results']

                if (len(data) > 0):
                    for result in data:
                        print("Type: " + result[0])
                        print("Value: " + result[1] + "\n")
                else:
                    print('No barcode detected.')
            except:
                break
            
        self.npSocket.endClient()      

Run pc.py in Windows and run rpi.py on Raspberry Pi. I used the resolution of 640×480 for preview and resized the frame size for TCP/IP transfer.

Raspberry Pi barcode detection

The barcode detection works stalely, and the average elapsed time is less than 150ms.

Reference

Source Code

https://github.com/yushulx/python-socket-rpi-barcode

The post Moving Heavy Computation from Raspberry Pi to Windows PC appeared first on Code Pool.

How to Build Web Barcode Apps with React and WebAssembly

$
0
0

Dynamsoft JavaScript barcode SDK is built based on WebAssembly, which provides high performance for reading barcodes in web apps. This tutorial aims to demonstrate how to quickly create a simple web barcode reader by using React and Dynamsoft JavaScript barcode SDK.

Download

Node.js

A Simple Web Barcode Reader

Create a new react app:

npx create-react-app react-wasm-barcode 
cd react-wasm-barcode

Load and initialize the JavaScript barcode library in public/index.html:

<img src="loading.gif" style="margin-top:10px" id="anim-loading">
<script src="https://demo.dynamsoft.com/dbr_wasm/js/dbr-6.4.1.1.min.js"></script>
<script>
  dynamsoft.dbrEnv.resourcesPath = 'https://demo.dynamsoft.com/dbr_wasm/js';
  dynamsoft.dbrEnv.onAutoLoadWasmSuccess = function () {
    window.reader = new dynamsoft.BarcodeReader();
    document.getElementById('anim-loading').style.display = 'none';
  };
  dynamsoft.dbrEnv.onAutoLoadWasmError = function (ex) {
    document.getElementById('anim-loading').style.display = 'none';
    alert('Fail to load the wasm file.');
  };
  //https://www.dynamsoft.com/CustomerPortal/Portal/TrialLicense.aspx
  dynamsoft.dbrEnv.licenseKey = "<Your Barcode License>";
</script>

If you do not have a valid license, you can register a Dynamsoft account and get a 30-day free trial license. To make the barcode reader globally accessible, assign the object to window.reader.

Create a barcode component in Barcode.js:

import React, { Component }from 'react';
export class Barcode extends Component {
    onChanged() {
        let image = document.getElementById('uploadImage').files[0];
        if (!image) {
            alert('Please add an image');
            return;
        }
        window.reader.decodeFileInMemory(image).then(function(results){
            var txts = [];
            for(var i=0;i<results.length;++i){
                txts.push(results[i].BarcodeText);
            }
            alert(txts.join("\n"));
        }).catch(ex => {
            alert('error:' + (ex.message || ex));
        });
    }
   
    render() {
      return (
        <div>
          <input id="uploadImage" type="file" accept="image/bmp,image/jpeg,image/png,image/gif" onChange={this.onChanged}/>
        </div>
      );
    }
  }

Use the Input element to load an image and write the barcode detection code in the onChanged() function.

Import the barcode component to App.js:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import {Barcode} from './Barcode';
 
class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <Barcode/>
        </header>
      </div>
    );
  }
}
 
export default App;

Run the app:

yarn start

Open localhost:3000 in your web browser to run the demo:

react web barcode reader

Source Code

https://github.com/dynamsoft-dbr/javascript-barcode/tree/master/examples/react-wasm-barcode

The post How to Build Web Barcode Apps with React and WebAssembly appeared first on Code Pool.

How to Build Python Barcode Apps with Qt on Windows

$
0
0

Qt for Python enables developers to quickly create GUI apps on Windows, Linux and macOS with one codebase. In this article, I will share how to build a Python barcode reader with Qt on Windows. Since Dynamsoft Barcode Reader SDK is also cross-platform, it is easy for you to reuse the sample code on Linux and macOS.

Installing Qt for Python on Windows

To install Qt for Python on Windows, you can either download a .whl file or run the command:

pip install pyside2

When using Python 3.6, I got the following error message:

Error:
Traceback (most recent call last):
File "test2.py", line 3, in <module>
from PySide2.QtWidgets import (QApplication, QLabel, QPushButton, QVBoxLayout, QWidget)
ImportError: DLL load failed: The specified procedure could not be found.

My workaround is to install Python 3.7 instead.

Dynamsoft Barcode Reader

A Simple Python Barcode Reader with Windows GUI

Qt designer

If you feel inconvenient to build UI programmatically, you can use Qt designer which is located at Python37\Lib\site-packages\PySide2\designer.exe.

Qt designer

After designing the UI by simply dragging the widgets, you can save the project to a *.ui file.

Next, convert the *.ui file to Python code with E:\Programs\Python\Python37\Scripts\pyside2-uic.exe:

pyside2-uic -x *.ui -o ui.py

Python barcode reader with Windows UI elements

We can quickly set up an app skeleton by reading the Qt for Python homepage.

My UI contains a button, a label, and a text area:

  • Button: pop up a system dialog to load image files from local disks.
  • Label: display the loaded images.
  • Text area: show barcode results.

Here is the code snippet:

import sys
from PySide2.QtGui import QPixmap
 
from PySide2.QtWidgets import QApplication, QLabel, QPushButton, QVBoxLayout, QWidget, QFileDialog, QTextEdit, QSizePolicy
from PySide2.QtCore import Slot, Qt, QStringListModel, QSize
 
import dbr
import os
 
class UI_Window(QWidget):
 
    def __init__(self):
        QWidget.__init__(self)
 
        # The default barcode image.
        dir_path = os.path.dirname(os.path.realpath(__file__))
        filename = os.path.join(dir_path, 'image.tif')
 
        # Create a layout.
        layout = QVBoxLayout()
 
        # Add a button
        self.btn = QPushButton("Load an image")
        self.btn.clicked.connect(self.pickFile)
        layout.addWidget(self.btn)
 
        # Add a label
        self.label = QLabel()
        self.label.setFixedSize(640, 640)
        pixmap = self.resizeImage(filename)
        self.label.setPixmap(pixmap)
        layout.addWidget(self.label)
 
        # Add a text area
        self.results = QTextEdit()
        self.readBarcode(filename)
        layout.addWidget(self.results)
 
        # Set the layout
        self.setLayout(layout)
        self.setWindowTitle("Dynamsoft Barcode Reader")
        self.setFixedSize(800, 800)

Connect the button to a click event:

def pickFile(self):
        # Load an image file.
        filename = QFileDialog.getOpenFileName(self, 'Open file',
                                               'E:\\Program Files (x86)\\Dynamsoft\\Barcode Reader 6.4.1\\Images', "Barcode images (*)")
        # Show barcode images
        pixmap = self.resizeImage(filename[0])
        self.label.setPixmap(pixmap)
 
        # Read barcodes
        self.readBarcode(filename[0])

Scale the loaded image to fit into the label:

def resizeImage(self, filename):
        pixmap = QPixmap(filename)
        lwidth = self.label.maximumWidth()
        pwidth = pixmap.width()
        lheight = self.label.maximumHeight()
        pheight = pixmap.height()
 
        wratio = pwidth * 1.0 / lwidth
        hratio = pheight * 1.0 / lheight
 
        if pwidth > lwidth or pheight > lheight:
            if wratio > hratio:
                lheight = pheight / wratio
            else:
                lwidth = pwidth / hratio
 
            scaled_pixmap = pixmap.scaled(lwidth, lheight)
            return scaled_pixmap
        else:
            return pixmap

Call barcode decoding method and then update the text area with the returned results:

def readBarcode(self, filename):
        dbr.initLicense("<Your License>")
        results = dbr.decodeFile(filename, 0x3FF | 0x2000000 | 0x4000000 | 0x8000000 | 0x10000000)
 
        out = ''
        index = 0
        for result in results:
            out += "Index: " + str(index) + "\n"
            out += "Barcode format: " + result[0] + '\n'
            out += "Barcode value: " + result[1] + '\n'
            out += '-----------------------------------\n'
            index += 1
 
        self.results.setText(out)

Run the app:

python barcode-reader.py

Qt Python barcode reader

Source Code

https://github.com/dynamsoft-dbr/python/tree/master/examples/qt

The post How to Build Python Barcode Apps with Qt on Windows appeared first on Code Pool.

How to Use Python and PyQt to Read Barcodes from Webcam

$
0
0

In my previous article, I shared how to use PyQt and Dynamsoft Barcode Reader to create a simple Windows-styled GUI app to read barcodes from image files. Now I am going to add a little bit more code to scan barcodes from the webcam video stream.

Showing Webcam Video Stream using PyQt

Usually, we can use OpenCV for Python to capture webcam frames.

pip install opencv-python

The code is pretty simple:

import cv2
vc = cv2.VideoCapture(0)
while True:
        rval, frame = vc.read()
        cv2.imshow("Camera View", frame)

When using PyQt, we cannot keep drawing the frames in an infinite loop in the main thread. Instead, we need to use a timer. I got the workaround from the StackOverflow Q&A:

def __init__(self):
        # Create a timer.
        self.timer = QTimer()
        self.timer.timeout.connect(self.nextFrameSlot)
 
def nextFrameSlot(self):
        rval, frame = self.vc.read()
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        image = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
        pixmap = QPixmap.fromImage(image)
        self.label.setPixmap(pixmap)
 
        results = dbr.decodeBuffer(frame, 0x3FF | 0x2000000 | 0x4000000 | 0x8000000 | 0x10000000)
        out = ''
        index = 0
        for result in results:
            out += "Index: " + str(index) + "\n"
            out += "Barcode format: " + result[0] + '\n'
            out += "Barcode value: " + result[1] + '\n'
            out += '-----------------------------------\n'
            index += 1
 
        self.results.setText(out)

In the function that triggered periodically via the timer, we can use OpenCV to capture a frame and decode the frame by calling the API of Dynamsoft Barcode Reader SDK. Note: before creating a QImage with the frame, we have to convert the color space of the frame from BRG to RGB.

Create a horizontal layout QHBoxLayout, which contains two buttons:

button_layout = QHBoxLayout()
 
btnCamera = QPushButton("Open camera")
btnCamera.clicked.connect(self.openCamera)
button_layout.addWidget(btnCamera)
 
btnCamera = QPushButton("Stop camera")
btnCamera.clicked.connect(self.stopCamera)
button_layout.addWidget(btnCamera)
 
layout.addLayout(button_layout)

Connect the buttons to some click events:

def openCamera(self):
        self.vc = cv2.VideoCapture(0)
        # vc.set(5, 30)  #set FPS
        self.vc.set(3, 640) #set width
        self.vc.set(4, 480) #set height
 
        if not self.vc.isOpened(): 
            msgBox = QMessageBox()
            msgBox.setText("Failed to open camera.")
            msgBox.exec_()
            return
 
        self.timer.start(1000./24)
     
def stopCamera(self):
        self.timer.stop()

Use closeEvent to pop up a confirm box for exit prompt:

def closeEvent(self, event):
     
        msg = "Close the app?"
        reply = QMessageBox.question(self, 'Message', 
                        msg, QMessageBox.Yes, QMessageBox.No)
 
        if reply == QMessageBox.Yes:
            event.accept()
            self.stopCamera()
        else:
            event.ignore()

Run the app:

Python barcode

Source Code

https://github.com/dynamsoft-dbr/python/tree/master/examples/qt

The post How to Use Python and PyQt to Read Barcodes from Webcam appeared first on Code Pool.


How to Build Web Barcode Scanner Using React and Webcam

$
0
0

Someone asked me how to create a real-time web barcode scanning app with a webcam. Is it hard to implement it? I’ve written an article sharing how to integrate Dynamsoft JavaScript Barcode Reader SDK into a React project. The remaining work is to make a webcam component. Since there is an open source project called react-webcam, we don’t need to reinvent the wheel. In this article, I will share how to build a web barcode scanner step by step.

Camera-based Web Barcode Scanning Component

Download and open react-webcam.js.

Find render() function to add a button and a canvas. We use the button to trigger barcode scan and render barcode results on the canvas:

render() {
    return (
      <div id='videoview' width={this.props.width} height={this.props.height}>
        <button onClick={this.scanBarcode}>Scan Barcodes</button>
        <video
          autoPlay
          width={this.props.width}
          height={this.props.height}
          src={this.state.src}
          muted={this.props.audio}
          className={this.props.className}
          playsInline
          style={this.props.style}
          ref={(ref) => {
            this.video = ref;
          }}
        />
        <canvas id="overlay" width={this.props.width} height={this.props.height}></canvas>
      </div>
    );
  }

To show the results on the video, we need to adjust the styles of the HTML elements. Create a react-webcam.css file:

#videoview {
    position: relative;
    width: 640px;
    height: 480px;
  }
 
#video {
    position: relative;
    width: 100%;
    height: 100%;
    z-index: 1
}
 
#overlay {
    position: absolute;
    top: 100;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 2
}

Import the CSS file in the react-webcam.js file:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import './react-webcam.css';

Create a scanBarcode() function, in which we need to get the byte array of the video frame and then call the decodeBuffer() method:

scanBarcode() {
    if (window.reader) {
      let canvas = document.createElement('canvas');
      canvas.width = this.props.width;
      canvas.height = this.props.height
      let ctx = canvas.getContext('2d');
      ctx.drawImage(this.video, 0, 0, this.props.width, this.props.height);
     
      window.reader.decodeBuffer(
        ctx.getImageData(0, 0, canvas.width, canvas.height).data,
        canvas.width,
        canvas.height,
        canvas.width * 4,
        window.dynamsoft.BarcodeReader.EnumImagePixelFormat.IPF_ARGB_8888
      )
      .then((results) => {
        this.showResults(results);
      });
    }
     
  }

How to make the window.reader initialized? In public/index.html, create the instance of the barcode reader and make it globally accessible once the wasm file is loaded:

<body>
    <img src="loading.gif" style="margin-top:10px" id="anim-loading">
    <script src="https://demo.dynamsoft.com/dbr_wasm/js/dbr-6.4.1.3.min.js"></script>
    <script>
      dynamsoft.dbrEnv.resourcesPath = 'https://demo.dynamsoft.com/dbr_wasm/js';
      dynamsoft.dbrEnv.onAutoLoadWasmSuccess = function () {
        window.reader = new dynamsoft.BarcodeReader();
        window.dynamsoft = dynamsoft;
        document.getElementById('anim-loading').style.display = 'none';
      };
      dynamsoft.dbrEnv.onAutoLoadWasmError = function (ex) {
        document.getElementById('anim-loading').style.display = 'none';
        alert('Fail to load the wasm file.');
      };
      dynamsoft.dbrEnv.bUseWorker = true;
 
      // Get a free trial license from https://www.dynamsoft.com/CustomerPortal/Portal/TrialLicense.aspx
      dynamsoft.dbrEnv.licenseKey = "Your Barcode SDK License"
 
    </script>
    <div id="root"></div>

Note: dynamsoft.dbrEnv.bUseWorker has to be true. If we do not use web worker, the main thread will be heavily blocked.

To make this work in scanBarcode(), bind it in the constructor:

constructor() {
super();
this.state = {
hasUserMedia: false,
};
this.scanBarcode = this.scanBarcode.bind(this);
}

The following code shows how to continuously scan and show the barcode results on the webcam video:

showResults(results) {
    let context = this.clearOverlay();
    let txts = [];
    try {
      let localization;
      for (var i = 0; i < results.length; ++i) {
        if (results[i].LocalizationResult.ExtendedResultArray[0].Confidence >= 30) {
          txts.push(results[i].BarcodeText);
          localization = results[i].LocalizationResult;
          this.drawResult(context, localization, results[i].BarcodeText);
        }
      }
       
      this.scanBarcode();
       
    } catch (e) {
      this.scanBarcode();
    }
  }
 
clearOverlay() {
    let context = document.getElementById('overlay').getContext('2d');
    context.clearRect(0, 0, this.props.width, this.props.height);
    context.strokeStyle = '#ff0000';
    context.lineWidth = 5;
    return context;
  }
   
drawResult(context, localization, text) {
    context.beginPath();
    context.moveTo(localization.X1, localization.Y1);
    context.lineTo(localization.X2, localization.Y2);
    context.lineTo(localization.X3, localization.Y3);
    context.lineTo(localization.X4, localization.Y4);
    context.lineTo(localization.X1, localization.Y1);
    context.stroke();
   
    context.font = '18px Verdana';
    context.fillStyle = '#ff0000';
    let x = [ localization.X1, localization.X2, localization.X3, localization.X4 ];
    let y = [ localization.Y1, localization.Y2, localization.Y3, localization.Y4 ];
    x.sort(function(a, b) {
      return a - b;
    });
    y.sort(function(a, b) {
      return b - a;
    });
    let left = x[0];
    let top = y[0];
   
    context.fillText(text, left, top + 50);
  }

Open App.js to add the React webcam component:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import {Barcode} from './Barcode';
import Webcam from './react-webcam';
 
class App extends Component {
  render() {
    return (
      <div className="App">
        <Barcode/>
        <Webcam />
      </div>
    );
  }
}
 
export default App;

Run the web barcode scanner app:

npm start

Visit localhost:3000:

react web barcode scanner webcam

Source Code

https://github.com/dynamsoft-dbr/javascript-barcode/tree/master/examples/react-wasm-barcode

The post How to Build Web Barcode Scanner Using React and Webcam appeared first on Code Pool.

Moving Heavy Computation from Raspberry Pi to Windows PC

$
0
0

If you want to use Raspberry Pi as an economical way of detecting barcodes, you can take account for Dynamsoft Barcode Reader SDK. As a business software, Dynamsoft Barcode Reader SDK is designed for overcoming a variety of complicated scenarios with sophisticated algorithms and heavy computations. Although the SDK is flexible for customizing algorithm parameters, subject to the low-frequency CPU of Raspberry Pi, the tradeoff between recognition accuracy and detection speed is still a big challenge. In this article, I will use Socket client-server model as a substitute solution. Thanks to Sabjorn’s NumpySocket module.

System Requirements

Python Barcode Reader Module

Install Dynamsoft Barcode Reader and follow the GitHub repository to build and install the Python barcode module.

Why do We Need the Socket Client-Server Model for Raspberry Pi

I am using the Raspberry Pi 3 Model B+:

  • Broadcom BCM2837B0, Cortex-A53 (ARMv8) 64-bit SoC @ 1.4GHz
  • 1GB LPDDR2 SDRAM

Here is the time cost of calling the barcode decoding method on Raspberry Pi. Let’s see the resolution of 640×480 first.

Raspberry Pi barcode native

The average elapsed time is more than 400ms. What about the resolution of 320×240?

Raspberry Pi barcode native 320x240

It seems a little bit better but not stable. The CPU utilization may reach 100% which will freeze the process. That is why we need the Socket client-server model by which we can continuously send video frames from Raspberry Pi to a remote server and execute barcode detection tasks on the server.

How to Implement the C/S Model for Barcode Detection

Install OpenCVscipy, and pillow on Raspberry Pi:

$ sudo apt-get install libopencv-dev python-opencv python-scipy 
$ python -m pip install pillow

Download NumpySocket. The Python module has already implemented the function of transferring the NumPy array. I only added two methods for sending and receiving barcode results in JSON formats:

import json
def sendJSON(self, data):
    out = json.dumps(data)
 
    try:
        self.connection.sendall(out)
    except Exception:
        exit()
 
def receiveJSON(self):
    try:
        chunk = self.socket.recv(1024)    
    except Exception:
        exit()
             
    return json.loads(chunk)

Create a pc.py file:

from numpysocket import NumpySocket
import cv2
import time
import json
import dbr
 
# Get the license of Dynamsoft Barcode Reader from https://www.dynamsoft.com/CustomerPortal/Portal/Triallicense.aspx
dbr.initLicense('LICENSE KEY')
 
npSocket = NumpySocket()
npSocket.startServer(9999)
 
# Receive frames for barcode detection
while(True):
    try:
        frame = npSocket.recieveNumpy()
        # cv2.imshow('PC Reader', frame)
        results = dbr.decodeBuffer(frame, 0x3FF | 0x2000000 | 0x4000000 | 0x8000000 | 0x10000000)
        out = {}
        out['results'] = results
 
        # Send barcode results to Raspberry Pi
        npSocket.sendJSON({'results': results})
    except:
        break
     
    # Press ESC to exit
    key = cv2.waitKey(20)
    if key == 27 or key == ord('q'):
        break
 
npSocket.endServer()
print('Closed')

In the infinite loop, receive the video frames from Raspberry Pi and then call barcode decoding function to get the results.

Create a rpi.py file. In this file, create a queue for storing and sharing video frames between threads:

def read_barcode():
    vc = cv2.VideoCapture(0)
    vc.set(3, 640) #set width
    vc.set(4, 480) #set height
 
    if not vc.isOpened():
        print('Camera is not ready.')
        return
 
    host_ip = '192.168.8.84'
    npSocket = NumpySocket()
    npSocket.startClient(host_ip, 9999)
 
    socket_thread = SocketThread('SocketThread', npSocket)
    socket_thread.start() 
 
    while vc.isOpened():
         
        ret, f = vc.read()
        cv2.imshow("RPi Reader", f)
        frame = imresize(f, .5)
 
        key = cv2.waitKey(20)
        if key == 27 or key == ord('q'):   
            socket_thread.isRunning = False
            socket_thread.join() 
            break
 
        if not socket_thread.is_alive():
            break
         
        try:
            frame_queue.put_nowait(frame)
        except:
            # Clear unused frames
            try:
                while True:
                    frame_queue.get_nowait()
            except:
                pass
 
    frame_queue.close()
    frame_queue.join_thread()
    vc.release()

Create a worker thread for Socket connection:

class SocketThread (threading.Thread):
    def __init__(self, name, npSocket):
        threading.Thread.__init__(self)
        self.name = name
        self.npSocket = npSocket
        self.isRunning = True
 
    def run(self):      
        while self.isRunning:
            frame = frame_queue.get(timeout=100)
 
            try:
                start_time = time.time()
                self.npSocket.sendNumpy(frame)
                obj = self.npSocket.receiveJSON()
                print("--- %.2f ms seconds ---" % ((time.time() - start_time) * 1000))
                data = obj['results']
 
                if (len(data) > 0):
                    for result in data:
                        print("Type: " + result[0])
                        print("Value: " + result[1] + "\n")
                else:
                    print('No barcode detected.')
            except:
                break
             
        self.npSocket.endClient()

Run pc.py in Windows and run rpi.py on Raspberry Pi. I used the resolution of 640×480 for preview and resized the frame size for TCP/IP transfer.

Raspberry Pi barcode detection

The barcode detection works stalely, and the average elapsed time is less than 150ms.

Reference

Source Code

https://github.com/yushulx/python-socket-rpi-barcode

The post Moving Heavy Computation from Raspberry Pi to Windows PC appeared first on Code Pool.

Android Barcode Detection from Fast Moving Objects

$
0
0

Assume you apply barcode technology to the logistics conveyor belt for scanning parcels. A problem you may face is how to recognize barcodes from blurred images. Although we can use advanced algorithms to deal with this complicated case, we’d better improve the image quality as possible as we can. A simple way is to adjust the camera shutter speed which is also known as exposure time. Faster shutter speed can avoid motion blur. In this post, I will share how to invoke Android Camera2 APIs to change the shutter speed, as well as how to build a simple Android barcode reader to decode barcodes from fast-moving objects

Android Barcode Reader with Camera2 API

To build a basic Android Camera2 app, we don’t need to reinvent the wheel. Just download or fork the source code of android-Camera2Basic provided by Google.

Create an AlertDialog with a list view for selecting shutter speed:

Activity activity = getActivity();
if (null != activity) {
    // https://stackoverflow.com/questions/15762905/how-can-i-display-a-list-view-in-an-android-alert-dialog
    AlertDialog.Builder builder = new AlertDialog.Builder(activity);
    builder.setTitle("Shutter Speed");

    final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(activity, android.R.layout.select_dialog_singlechoice);
    arrayAdapter.add("1/1000 s");
    arrayAdapter.add("1/500 s");
    arrayAdapter.add("1/250 s");
    arrayAdapter.add("1/125 s");
    arrayAdapter.add("1/100 s");

    builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
        }
    });

    builder.setAdapter(arrayAdapter, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            mShutterSpeed = SHUTTER_SPEED.get(which);
            startPreview();
        }
    });
    builder.show();
}

Get a list of sizes compatible with the requested image format YUV_420_888 and instantiate ImageReader with the opted image size:

Size outputPreviewSize = new Size(MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT);
Size[] sizeList =  map.getOutputSizes(ImageFormat.YUV_420_888);
for (Size size : sizeList) {
    if(size.getWidth() * size.getHeight() > 1000000)
        continue;
    else{
        outputPreviewSize = size;
        break;
    }
}

mImageReader = ImageReader.newInstance(outputPreviewSize.getWidth(), outputPreviewSize.getHeight(),
        ImageFormat.YUV_420_888, 4);

In the ImageReader callback function onImageAvailable(), get the image buffer and call the decodeBuffer() function for barcode detection:

    Image image = reader.acquireLatestImage();
    if (image == null) return;

    ByteBuffer buffer = image.getPlanes()[0].getBuffer();
    byte[] bytes = new byte[buffer.remaining()];
    buffer.get(bytes);
    int nRowStride = image.getPlanes()[0].getRowStride();
    int nPixelStride = image.getPlanes()[0].getPixelStride();
    image.close();
    try {
        TextResult[] results = mBarcodeReader.decodeBuffer(bytes, mImageReader.getWidth(), mImageReader.getHeight(), nRowStride * nPixelStride, EnumImagePixelFormat.IPF_NV21, "");
        String output = "";
        if (results != null && results.length > 0) {
            for (TextResult result: results) {
                String format = result.barcodeFormatString;
                String text = result.barcodeText;

                output += "Format: " + format + ", Text: " + text;
            }
        }
        else {
            output = "";
        }

        Message msg = new Message();
        msg.what = MSG_UPDATE_TEXTVIEW;
        msg.obj = output;
        mMainHandler.sendMessage(msg);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

Because the listener is invoked on a thread handler, we can not update the UI directly.  We can send an update request via the main thread handler:

mMainHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_UPDATE_TEXTVIEW:
                String result = (String)msg.obj;
                mTextView.setText((String)msg.obj);

                if (!result.equals("")) {
                    mToneGenerator.startTone(ToneGenerator.TONE_PROP_BEEP2);
                }

        }
    }
};

Add the ImageReader surface to the CaptureRequest.Builder:

mPreviewRequestBuilder.addTarget(mImageReader.getSurface());

Start the preview when the camera capture session is ready. To control the shutter speed, turn off the auto-exposure mode:

try {
    // Auto focus should be continuous for camera preview.
    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
            CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);

    // Adjust the shutter speed
    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
    mPreviewRequestBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, mShutterSpeed);

    // Finally, we start displaying the camera preview.
    mPreviewRequest = mPreviewRequestBuilder.build();
    mCaptureSession.setRepeatingRequest(mPreviewRequest,null,null);
} catch (CameraAccessException e) {
    e.printStackTrace();
}

Now build and run the simple Android barcode reader. If the barcodes cannot be read from the fast-moving objects, you just need to change the shutter speed:

Android barcode reader with Camera2 API

Note: due to the hardware specs, you may get low-quality preview images on some cheap phones when changing the shutter speed to 1/500 seconds or faster.

Source Code

https://github.com/yushulx/android-camera2-barcode

The post Android Barcode Detection from Fast Moving Objects appeared first on Code Pool.

Making a Barcode Scan Robot with Lego Boost and Webcam

$
0
0

If you want to quickly create a walking robot, you can use the Lego Boost. In this post, I will share how to use a webcam, Lego Boost, and Dynamsoft Barcode Reader SDK to make a robot for scanning barcodes. The programming language used in this article is Python.

How to Build the Robot with Lego Boost

To build the robot, install the Boost app and follow the relevant tutorials.

lego boost robot

Python Programming Requirements

  • Download Dynamsoft Barcode Reader for Linux. After extracting the package, copy libDynamsoftBarcodeReader.so to /usr/lib.
  • Get a free 30-day trial license of Dynamsoft Barcode SDK.
  • Get the source code of Dynamsoft Python barcode module and follow the steps to build and install.
  • Install one of the Bluetooth backends:
    pip install pygatt
    pip install gatt
    pip install gattlib
    pip install bluepy
  • Install pylgbst to interact with Lego Boost Move Hub:
    pip install https://github.com/undera/pylgbst/archive/1.0.tar.gz
  • Install OpenCV Python:
    pip install opencv-python
    # or
    pip3 install opencv-python

How to Control Lego Boost Robot to Scan Barcodes

Create a camera view window using OpenCV:

    vc = cv2.VideoCapture(0)
    vc.set(3, 640) #set width
    vc.set(4, 480) #set height

    if vc.isOpened():  # try to get the first frame
        rval, frame = vc.read()
    else:
        return

    windowName = "Robot View"
    
    try:
        while True:
            rval, frame = vc.read()
            cv2.imshow(windowName, frame)

Due to GIL (Python Global Interpreter Lock), we need to run Bluetooth connection code and barcode decoding algorithm in another process rather than thread. All data, including key events, webcam frames, and barcode results, are transferred via Queue:

    num = Value('i', 1)
    result_queue = Queue(1)
    key_queue = Queue(1)
    frame_queue = Queue(1)
    cond = Condition()
    dbr_proc = Process(target=dbr_run, args=(
        frame_queue, key_queue, cond, num, result_queue))
    dbr_proc.start()

Here are the key definitions:

  • a: left
  • d: right
  • w: up
  • s: down
  • q: terminate the app
  • c: capture images and scan barcodes

The code for controlling the Lego Boost Robot is pretty simple. I use Gatt Backend:

conn GattConnection()  
try:
    conn.connect()
    hub = MoveHub(conn)
    print('Robot connected')
    speed = 0.5
                
    if key == ord('a'):
        # left
        hub.motor_AB.angled(90, speed * -1, speed)
    elif key == ord('d'):
        # right
        hub.motor_AB.angled(90, speed, speed * -1)
    elif key == ord('w'):
        # up                    
        hub.motor_AB.start_speed(speed)
    elif key == ord('s'):
        # down
        hub.motor_AB.start_speed(speed * -1)
    elif key == ord('p'):
        hub.motor_AB.stop()
finally:
    conn.disconnect()

Read the QR code and put the results into the queue:

dbr.initLicense('LICENSE-KEY')

if key == ord('c'):
    inputframe = frame_queue.get()
    results = dbr.decodeBuffer(inputframe, 0x4000000)
    if (len(results) > 0):
        for result in results:
            print("Type: " + result[0])
            print("Value: " + result[1] + "\n")

    result_queue.put(Result(inputframe, results))

Draw the barcode position and decoded text result using OpenCV:

                ret = result_queue.get_nowait()
                results = ret.results
                image = ret.image

                thickness = 2
                color = (0,255,0)
                for result in results:
                    print("barcode format: " + result[0])
                    print("barcode value: " + result[1])
                    x1 = result[2]
                    y1 = result[3]
                    x2 = result[4]
                    y2 = result[5]
                    x3 = result[6]
                    y3 = result[7]
                    x4 = result[8]
                    y4 = result[9]

                    cv2.line(image, (x1, y1), (x2, y2), color, thickness)
                    cv2.line(image, (x2, y2), (x3, y3), color, thickness)
                    cv2.line(image, (x3, y3), (x4, y4), color, thickness)
                    cv2.line(image, (x4, y4), (x1, y1), color, thickness)

                    cv2.putText(image, result[1], (min([x1, x2, x3, x4]), min([y1, y2, y3, y4])), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), thickness)

                cv2.imshow("Localization", image)

Run the app:

python3 app.py

Lego Boost webcam barcode

Source Code

https://github.com/yushulx/lego-boost-webcam-barcode

The post Making a Barcode Scan Robot with Lego Boost and Webcam appeared first on Code Pool.

Bundling Dynamsoft JavaScript Barcode Library with Webpack

$
0
0

Webpack is a JavaScript module bundler. It is widely used in web frameworks, such as React and Angular. This tutorial shows how to implement a simple web barcode reading app with webpack and Dynamsoft JavaScript Barcode library.

Setting Up a Basic Project with Webpack

Create a directory. Initialize the project and install webpack via npm:

mkdir webpack-dbr
cd webpack-dbr
npm init -y
npm install webpack --save-dev
npm install webpack-cli --save-dev

Create webpack.config.jssrc\index.js, and index.html.

Webpack.config.js is the configuration file used for bundling JavaScript modules:

const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    }
};

The script above takes the ./src/index.js as the entry point and generates a dist/bundle.js as the output. So in index.html, we only need to include dist/bundle.js:

<!doctype html>
<html>
  <head>
  </head>
  <body>
    <script src="dist/bundle.js"></script>
  </body>
</html>

Before adding the barcode logic to index.js, let’s build the bundle.js file with the following command:

npx webpack --config webpack.config.js

The npx command is used to execute local npm package binaries. If you have installed webpack globally, you can run:

webpack --config webpack.config.js

Bundling Dynamsoft JavaScript Barcode

Download Dynamsoft JavaScript Barcode library:

npm install dynamsoft-javascript-barcode

Get a free trial license key.

Add the following code to index.js:

const BarcodeReader = require('dynamsoft-javascript-barcode')

BarcodeReader.licenseKey = 'LICENSE-KEY';
let scanner = new BarcodeReader.Scanner({
    onFrameRead: results => { console.log(results); },
    onNewCodeRead: (txt, result) => { alert(txt); }
});
scanner.open();

Try to run the build. You will see the error message below:

webpack javascript barcode error

To solve the “Module not found: Error: Can’t resolve ‘fs’” error, open webpack.config.js to add:

const path = require('path');

module.exports = {

entry: './src/index.js',
/////////////////////
    node: {
        fs: 'empty'
},
/////////////////////
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    }
};

Now you can successfully build the bundle.js file.

Install Web Server for Chrome to host the project, and then visit the index.html in Chrome.

dbrjs not found

Oops, error again. There are some files not found. We can use copy-webpack-plugin to copy the dependent files from node modules to the build directory. Install the webpack plugin:

npm install copy-webpack-plugin --save-dev

Add the plugin code in webpack.config.js:

const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');

module.exports = {
    plugins: [
        new CopyPlugin([
            {
                from: './node_modules/dynamsoft-javascript-barcode/dist',
                to: path.resolve(__dirname, 'dist'),
                ignore: ['*.ts'],
            }
        ]),
    ],

    entry: './src/index.js',
    node: {
        fs: 'empty'
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    }
};

Rebuild the project and refresh the web barcode reader app. It’s working:

javascript web barcode reader

Source Code

https://github.com/dynamsoft-dbr/javascript-barcode/tree/master/examples/webpack-dbr

 

The post Bundling Dynamsoft JavaScript Barcode Library with Webpack appeared first on Code Pool.

Viewing all 145 articles
Browse latest View live