Barcode scanning products. Technical Questions


1. [SDK] A barcode was not decoded. Why?
Our barcode reading engine uses various methods to achieve maximum recognition. But sometimes it is impossible to decode a barcode due to its poor quality. Send us this image, it may help us improve our software.
2. [SDK] 1 extra character in the code
We have used the SDK in our application to decode the Barcode(code-128)/QRCode, but it has decoded the code and appended 1 extra character. In our case:
Original: SOUKLNWUSCLLZHPP
SDK decodes: SOUKLNWUSCLLZHPP3
Same has happened with 1 other code in which extra 'D' is appended by the SDK at the end of the code.
What can be the possible reason for this? Please explain and suggest the solution.
Some barcode types contain check digit. Our SDK transfers the whole barcode with 1 (or 2 for Code93) extra character. You can change this behaviour using LinearShowCheckDigit property

Since version 5.62 we removed 1 check digit from Code-128 and 2 check from Code-93.
3. [SDK] How to find an undecoded barcode (or add barcode type)?
If a barcode is recognized but cannot be decoded can that information be made available from this SDK? For example, a smudge on the ticket is present. What type of information is provided back?
SDK for each platform contains BarcodeTypes property, you should to add required barcode type: The BarcodeTypes is binary combination of SDK supported types.
dec.BarcodeTypes = 0x40000000|0x08000000; //find QRCode and unrecognized QRCode
SDK returns all information as for decoded barcode excluding barcode text.
4. [SDK] Can I use the image just from the device memory?
After checked some document on your web, I have a question. Can I use the image just from the device memory? For example my source from the device:
IplImage * videoImgLearn; 
videoImgLearn = cvCreateImage (cvSize (m_nSizeX[0], m_nSizeY[0]), IPL_DEPTH_8U, 1);
videoImgLearn->imageData = (char*) m_pcImageMemory[0];
m_pcImageMemory[0] is from the device memory.
So, Can I directly use your method to send the m_pcImageMemory[0]? Would you pls give me an example?
[Windows SDK]
If your image in memory already converted to gray map you can use DecodeGrayMap.
If your image is encoded (jpg, tiff, bmp, etc.) you can use DecodeStream
The SDK examples contains source code how to use these methods.
[Android, Java SDK]
byte[] data; //contains gray scale image
//...
DecodingResult[] decRes = mbr.Decode(data, FrameWidth, FrameHeight, 0, 0, 0, 0);
[Linux/MacOS SDK]
int res = Decode(&m_pcImageMemory[0], width, height, 0);
5. [SDK. Windows] My file contains several barcodes, but only one barcode was decoded. Why did it happen?
First of all, check whether you use the standard or professional edition. The standard edition decodes only one barcode in a file.
If you use the professional edition, check how the properties are set. By default, this property is set to 1, i.e. only one barcode is decoded in a file. For example, if you want to decode up to 5 barcodes, set the required property to 5.
6. [SDK. Windows] Cannot decode PDF file
I download the demo (I use the vb6 project1 demo). I need to recognize a barcode in an image embedded in a PDF file. But when I tried to decode the PDF file, the demo stops with the message 'Error: PDF library not found' in the
cnt = BarcodeDecoder1.DecodeFile(Text1.Text)
statement.
You need to copy "qpdf.dll" file in folder where your VB6 application .exe file placed. The "qpdf.dll" you can find in
C:\Program Files\RKD\BarcodeReaderAx\32bit or 64 bit
or where you installed the SDK.
7. [SDK. Windows] How to use DecodeStream method?
I've got DecodeFile method to work fine with QR Code. But I can't make the DecodeStream to work. What should be the data structure required for the FileStream input? In the documentation said array of bytes, so I just send it the bitmap file data in bytes, but doesn't seem to work.
DecodeStream gets one dimension byte array. This byte array should to contain the whole image file (jpg, bmp, png, etc.) like on the disk. See VB6 example
Dim bytes() As Byte

bytes = ReadFile("c:\MyFolder\linear-7.gif")

c = BarcodeDecoder1.DecodeStream(bytes)

For i = 0 To BarcodeDecoder1.Barcodes.length - 1
	Dim bc As Barcode
	Set bc = BarcodeDecoder1.Barcodes.Item(i)
	txt = bc.Text
	MsgBox txt
Next i
8. [SDK. Windows] Is there a way to integrate the SDK into a WPF (Windows Presentation Foundation)?
Yes you can use it in WPF application. Our SDK contains WPF app source code here:
../Program Files/RKD/BarcodeReaderAx/32bit/Examples/C#/WpfApplication1
9. [SDK. Windows] How to activate in silent mode?
Can you please provide instructions for running the activation program in silent mode?
You have several ways to do it.
  • You can Install and Activate at once using our installation program.
    BarcodeReader.exe /VERYSILENT /t 030-XXXXXXXX
    where:
    030-XXXXXXXX is your Activation Key

  • If you need just to activate then start ActivateSoft program like
    ActivateSoft.exe /t 030-XXXXXXXX
    or
    ActivateSoft.exe /v /t 030-XXXXXXXX
    /v - start the ActivateSoft.exe program in visible mode.

  • You can request the key from our activation server via HTTPS and save it in Windows registry. We send the C# source code on request.
10. [SDK. Windows] How to use your Barcode Reader SDK in Java application?
How to use your Barcode Reader SDK in Java application?

The following information is only for Windows platform. You can still use it in Windows application. But now we recommend the native (for Windows/Linux/MacOS) Java SDK.

To use Barcode Reader ActiveX in a Java application, you need to use special software to connect COM and Java for instance, JACOB. This combination will only work on a Windows machine. Below is an example of a Java application that calls the methods of our barcode decoding SDK.
[Java]

import com.jacob.com.*;
import com.jacob.activeX.*;

public class BarcodeReader
{
  public static void main(String args[])
  {
    System.out.println("\nUsing www.DataSymbol.com Barcode Reader SDK in Java\n");

    try
    {
      ActiveXComponent barcodeDecoder = new ActiveXComponent("BarcodeReader.BarcodeDecoder");

      barcodeDecoder.setProperty("LinearFindBarcodes", new Variant(7));

      int cBarcodes = Dispatch.call(barcodeDecoder, "DecodeFile", 
        new Variant("c:\\barcodes.jpg")).getInt();
      System.out.println("Decoded barcodes: " + cBarcodes + "\n");

      if (cBarcodes != 0)
      {
        int i;
        Dispatch barcodeList = barcodeDecoder.getProperty("Barcodes").toDispatch();

        for (i = 0; i < cBarcodes; ++i)
        {
          Dispatch barcode = Dispatch.call(barcodeList, "item", new Variant(i)).toDispatch();
          System.out.println( Dispatch.get(barcode, "Text").getString() );
        }
      }
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      ComThread.Release();
    }
  }
}

Compiling Java application with DataSymbol.com Barcode Reader SDK

Java application as Barcode Reader

11. [SDK. Android] Missing a few characters. Why?
We are looking for barcode reader SDK on the Android. We gave a try your Android app. It seems it will get the barcode but it seems missing a few characters. For example, the full barcode is "C4AX1012000158". After scanning, it will get "**AX1012000158". Do you know why?
This is demo limitation. You should to activate the app. In production mode you will get the whole barcode text.
12. [SDK. Linux] How to use under Linux/MacOS?
On the list of supported platforms, it shows Linux. It looks like you only provide a DLL component. How would I run this under Linux? Is there a performance degradation because of this? And how would this run under Mac OSX?
We provide DLL only for Windows platform. We have the native 32&64 bit libraries for Linux and MacOS so you can use it without any problem.
13. [SDK. Java. Windows/Linux/MacOS] Cannot find any barcode using Java SDK.
I'm trying to use the following Java code.
Path path = Paths.get("/home/mike/Desktop/java/img_lin.pgm/barcode.jpg");
byte[] data = Files.readAllBytes(path);

DecoderParameters dp = new DecoderParameters();
dp.barcodeTypes = DecoderParameters.ST_CODE128|DecoderParameters.ST_CODE39;
dec.SetParams(dp);

DecodingResult res[] = dec.DecodePgm(data, 0, 0, 0, 0);

But it doesn't find any barcode in my image. Can you explain why?
You are trying to use the DecodePgm method. This method accepts only PGM (portable gray map) images. First you need to convert your jpeg, png, bmp (etc.) file in PGM or gray map. You can do it "manually" (for example, convert your image in RGB24 then using red, green and blue pixel components calculate the gray byte) or using Java methods (see the following code).
[SDK. Java]
BarcodeReaderWrapper dec = new BarcodeReaderWrapper();
if(!dec.InitLib(""))
{
      System.out.println(String.format("Error: %d", dec.decError));
      return;
}

DecoderParameters dp = new DecoderParameters();
dp.uiLinearFindBarcodes = 7;
dp.barcodeTypes = DecoderParameters.ST_CODE128|DecoderParameters.ST_CODE39|DecoderParameters.ST_INTERL25|
		DecoderParameters.ST_EAN13|DecoderParameters.ST_EAN8|DecoderParameters.ST_UPCA;
dec.SetParams(dp);

BufferedImage in = ImageIO.read( new File("/home/mike/Desktop/Images/linear-4.jpg") );
				
BufferedImage newImage = new BufferedImage(in.getWidth(), in.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
newImage.getGraphics().drawImage(in, 0, 0, null);
				
DataBufferByte buffer = (DataBufferByte) newImage.getRaster().getDataBuffer();
byte[] data = buffer.getData();
	
DecodingResult res[] = dec.Decode(data, in.getWidth(), in.getHeight(), 0, 0, 0, 0);

for(int j=0; res!=null && j < res.length; ++j)
{
	String sBarcode = new String( res[j].data, 0, res[j].data.length );
	System.out.println(sBarcode);
}
or
BarcodeReaderWrapper dec = new BarcodeReaderWrapper();
if(!dec.InitLib(""))
{
      System.out.println(String.format("Error: %d", dec.decError));
      return;
}

DecoderParameters dp = new DecoderParameters();
dp.uiLinearFindBarcodes = 7;
dp.barcodeTypes = DecoderParameters.ST_CODE128|DecoderParameters.ST_CODE39|DecoderParameters.ST_INTERL25|
		DecoderParameters.ST_EAN13|DecoderParameters.ST_EAN8|DecoderParameters.ST_UPCA;
dec.SetParams(dp);

BufferedImage in = ImageIO.read( new File("/home/mike/Desktop/Images/linear-4.jpg") );
		
int width = in.getWidth();
int height = in.getHeight();
BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
newImage.getGraphics().drawImage(in, 0, 0, null);
						
int[] pixels = ((DataBufferInt)newImage.getRaster().getDataBuffer()).getData();	//RGB

byte[] data = new byte[width * height];	//gray map

//convert in gray map
int i=0;
for( int row = 0; row < height; ++row )
{
	for( int col = 0; col < width; ++col)
	{
		int rgb = pixels[ row*width + col ];
		data[i++]=(byte)((299*(rgb & 0xFF) + 587*((rgb >>  8) & 0xFF) + 114*((rgb >> 16) & 0xFF))/1000);
	}
}

DecodingResult res[] = dec.Decode(data, width, height, 0, 0, 0, 0);

for(int j=0; res!=null && j < res.length; ++j)
{
	String sBarcode = new String( res[j].data, 0, res[j].data.length );
	System.out.println(sBarcode);
}
14. [SDK. Java. Windows/Linux/MacOS] Java UnsatisfiedLinkError.
I'm trying to use Java SDK and have the following error
Exception in thread "main" java.lang.UnsatisfiedLinkError: 
	com.myenv.BarcodeReaderWrapper.InitLib(Ljava/lang/String;)Z
	at com.myenv.BarcodeReaderWrapper.InitLib(Native Method)
	at Main.main(main.java:26)

I've copied libjnidsdecoder.so and libdsdecoder.so.1 files in /usr/lib folder
You should to place Java SDK files (BarcodeReaderWrapper.java, DecoderParameters.java, DecodingResult.java) in "com/datasymbol/barcodereader" of your "src" folder, but you copied in "com/myenv", this will not work.



1. [Web SDK] What is the best way to save the SDK key?
In case of updating of the library key in my JS file Web SDK remain operating in the demo mode. I install the key in the following way.
var scannerSettings = {
	scanner: {
		key: 'OZ1GQJIRv8V+wxBhzjs94LlcI3Wo6UC+qEV1vanpmUk ...',
		//...
	},
	//...
};

//...

DSScanner.Create(scannerSettings);

The client’s browser does not notice the updating and keeps on using the old key. How to change that?
The problem is most likely in the client’s browser which uses the cached version of your JS file. If JS file is changed, the browser should not use the cached version any longer. However, some browsers, especially mobile phone ones, use the old cached version.
Our barcode reader Web SDK does not use any online licenses (excluding "users per day" license) and makes no network activity as it works only offline in the client’s browser. Hence, only the key you transfer while creating a scanner in your JS code is used.
We offer two kinds of licenses, i.e. permanent and annual. In case of the permanent license you can record the key in your JS code without problems although it may not be quiet convenient from the administrating and code supporting point of view. In case of the annual license, we would recommend to store the key in any folder of your website and upload it online from JS code. The example below shows how to read out the key from key.txt file sharing the same folder with JS code:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'key.txt?r=' + Math.random(), true);
xhr.send();

xhr.onreadystatechange = function() {
	if (xhr.readyState != 4 )
		return;

	if (xhr.status != 200) {
		console.log('cannot get key|'+xhr.status);
	}
	else{
		var scannerSettings = {
			scanner: {
				key: xhr.responseText,
			},
			viewport: {
				id: 'datasymbol-barcode-viewport',
			},
			camera: {
				resx: 640,
				resy: 480,
			},
			barcode: {
				barcodeTypes: [Code128, DataMatrix],
			},
		};

		DSScanner.addEventListener('onError', onError);
		DSScanner.addEventListener('onBarcode', onBarcodeReady);
		DSScanner.addEventListener('onScannerReady', function () {
			console.log('HTML onScannerReady');
			DSScanner.StartScanner();
		});

		DSScanner.Create(scannerSettings);
	}
}

Math.Random() – adds a random number to URL to prevent a browser from caching a request.

Another method of preventing a browser from caching the file with the key is to add Cache-Control header to the reply from the server to key.txt file request:
Cache-Control: public, max-age=60

In this case you can request the "key.txt" file like (without "Math.Random")
xhr.open('GET', 'key.txt', true);

It is possible to do in .htaccess file on apache2 server (please see documentation how to do it on IIS):
# adds custom header for single file "key.txt" with barcode Web SDK key
# should be enabled "headers" module: sudo a2enmod headers, or use <IfModule mod_headers.c></IfModule>
<Files "key.txt">
	Header set Cache-Control "public, max-age=60"
</Files>

2. [Web SDK] Your example doesn’t work on IIS server. Why?
I downloaded your Web SDK and placed it in wwwroot folder of IIS server. In case of request:
http://localhost/websdk.html

the browser log contains a great number of strange mistakes:
wasm streaming compile failed: TypeError: Response has unsupported MIME type datasymbol-sdk-hlp.min.js:1:49391
falling back to ArrayBuffer instantiation datasymbol-sdk-hlp.min.js:1:49457
* DataSymbol|onModuleAbort datasymbol-sdk-hlp.min.js:1:6002
on the web, we need the wasm binary to be preloaded and set on Module['wasmBinary']. emcc.py will do that for you when generating HTML (but not JS) datasymbol-sdk-hlp.min.js:1:60293
on the web, we need the wasm binary to be preloaded and set on Module['wasmBinary']. emcc.py will do that for you when generating HTML (but not JS) datasymbol-sdk-hlp.min.js:1:60322
failed to asynchronously prepare wasm: abort("on the web, we need the wasm binary to be preloaded and set on Module['wasmBinary']. emcc.py will do that for you when generating HTML (but not JS)"). Build with -s ASSERTIONS=1 for more info. datasymbol-sdk-hlp.min.js:1:49003
* DataSymbol|onModuleAbort datasymbol-sdk-hlp.min.js:1:6002

You need to find out if .wasm file is available first. To do that enter the following in your browser:
http://localhost/datasymbol-sdk.wasm

if error 404 appears (but wasm file really exists)

404 error in IIS Internet Server when using datasymbol barcode decoding wasm, Web SDK

It means that most likely you need to add MIME type for wasm application. You can do it as follows:

add barcode decoder wasm (Web SDK) on IIS Server

add barcode decoder wasm (Web SDK) on IIS Server

add barcode decoder wasm (Web SDK) on IIS Server

See on Microsoft: Add a MIME Type (IIS 7)
3. [Web SDK] Response has unsupported MIME type. Why?
I noticed the following warning/error in the browser log:

wasm streaming compile failed: TypeError: Response has unsupported MIME type 
falling back to ArrayBuffer instantiation

At the same time Web SDK works properly and barcodes are decoded. I use Ubuntu/apache2 environment.
At receiving .wasm file request the browser should get correct Content-Type header. For wasm file it is:
Content-Type: application/wasm

We would recommend to transfer the header although everything works without it. It will allow to decrease your server load and to shorten the time of your web application in the client’s browser uploading. For instance, you may add the following command to .htaccess for apache2 server:
AddType application/wasm wasm
AddOutputFilterByType DEFLATE application/wasm
4. [Web SDK] Is it possible to place the .wasm file into a different folder?
Wasm and JS files are in the same folder in all your examples. Can I place wasm file in a different folder?
Yes, it is possible. To do that create the following global variable in your JavaScript code:
var DEF_WASM_PATH = '/js/datasymbol-sdk.wasm';

The variable should contain the path to your wasm file.
5. [Web SDK] Your barcode Web SDK does not work on my website.
I copied all of your Web SDK files on my server. However, the browser produces an "incompatible browser" mistake while trying to open URL of
http://mysite.com/websdk.html
Now you are using the HTTP protocol. Normally, browsers do not allow to use a web camera without HTTPS protocol. Hence, if you try to enter a website through HTTP it won’t work in the majority of browsers. To develop and test a local version of a website or to get an HTTP access feel free to use Firefox. However, in case of production you need to install a valid SSL certificate on your website.
6. [Web SDK] Browser does not use a modified version of the JS file.
After changes in some settings in JavaScript file of a scanner and its uploading on the website the browser keeps on using the old version. How can I improve the situation?
I guess that your browser uses the cached version of a JavaScript file. If you use a desktop browser, press on Ctrl+F5 to update your web page content completely. If your browser is installed on your mobile (iOS, Android, etc.) it, in the majority of cases, does not allow to update the content completely. In that case you can delete the cached data in the browser settings. In some OSes it can be dome for all the websites and in other cases it can’t be done.
7. [Web SDK] "Invalid constraint" exception in DSScanner.Create method.
When I surf with Safari on my iPhone 6 CreateScanner function shows "Invalid constraint" mistake whereas my PC doesn’t show that. I'm use the following barcode scanner settings.

var scannerSettings = {
	scanner: {
		beep: true,
		barcodeAtPoint: true
	},
	viewport: {
		id: 'scanner-container',
		width: 320,
	},
	camera: {
		resx: 320,
		facingMode: 'environment'
	},
	barcode: {
		barcodeTypes: ['Code39'],
	}
};
Mistake "Invalid constraint" most likely means that you use the resolution or any other parameter your device doesn’t support. Many browsers don’t fire a exception in that case. They use the nearest supported resolution themselves. Safari on iOS shows a mistake in that case.

In your case you have the problem with scannerSettings.camera.resx parameter. iPhone 6 doesn't support 320 frame resolution.
8. [Web SDK] License key doesn't work.
I have bought Barcode Web SDK license but the scanner keeps on working in demo mode as it replaces some of the barcode symbols to '*'. I use the following code:
function CreateScanner(device){
    var scannerSettings = {
        scanner: {
            key: '',
        },
        viewport: {
            id: 'datasymbol-barcode-viewport',
            width: 300,	//if not defined then 100%
        },
        camera: {
            resx: 640,
            facingMode: 'environment',
        },
        barcode: {
            barcodeTypes: ['EAN13', 'Code128', 'DataMatrix', 'QRCode', 'QRCodeUnrecognized'],
            bQRCodeFindMicro: false,
        },
    };

    DSScanner.addEventListener('onError', onError);
    DSScanner.addEventListener('onBarcode', onBarcodeReady);
    DSScanner.addEventListener('onScannerStarted', function() {
			console.log('HTML onScannerStarted');
		});
	
    DSScanner.addEventListener('onScannerReady', function (frameSize) {
        console.log('HTML onScannerReady|'+frameSize.width + '|'+frameSize.height);
		
		if( !bFirst ) {
			DSScanner.StartScanner();
			return;
		}

		bFirst = false;

        var statusElement = document.getElementById('status');
        statusElement.innerHTML = ' ';	//statusElement.hidden = true;
        DSScanner.StartScanner();

		//set scanning rect
		var scannerSettings = {
			scanner: {
                scanningRect: {left:0, top:0, width:0, height:0},
                key: 'xbU4DOZ1GQJIRv8V+wxBhzjs94LlcI3Wo6UC+qEV1v ...'
            },
		};
		DSScanner.setScannerSettings(scannerSettings);
	});

    DSScanner.Create(scannerSettings);
}
There is a mistake in your JavaScript. You should transfer the key while creating the scanner, i.e. while activating Create method. You simply transferred an empty key

    var scannerSettings = {
        scanner: {
            key: '',
        },
		//...
	};

Afterwards you set it with setScannerSettings method. It won’t work. Besides, we do not recommend to hard code the key into JavaScript. Please check where to store your license key here.
9. [Web SDK] How to use a back camera by default?
When testing it on my iPhone using Safari, it is defaulting to the front camera. How can I change it to use the back camera?
You need to use "facingMode" parameter:
var scannerSettings = {
	camera: {
		facingMode: 'environment'
		//...
	},
	//...
};
10. [Web SDK] How to embed barcode scanner in WordPress

Note: We created a special WordPress Plugin. Therefore, you don't need to use the method described below.
 

Our online example: https://websdk.datasymbol.com/wp/
Your site should to use HTTPS (secure) connection (now this is requirement of all Internet browsers).

1. Download and unzip DataSymbol barcode scanner Web SDK for WordPress.
Download

2. Copy all files ("datasymbol-sdk.wasm", "datasymbol-sdk-hlp.min.js", "main.js") in any folder of your site.
In this tutorial, we will assume that the files are located in the "/wp/js/" folder. If you copy the files in other place you will need to change path in "main.js" and use changed paths in HTML code below.

3. You can customize barcode scanner settings in "main.js" file.

4. Install "Code Embed" (or any else) WordPress plugin.
install Code Embed for barcode scanner code WordPress embedding

5. Switch Editor to "Code Editor".
select code editor

6. Insert the following HTML code.
{{CODEWebSDK}}
<p id="status">Downloading ...</p>
<div id="datasymbol-barcode-viewport" style="display:block;width:90%;"></div>

code of page
"{{CODEWebSDK}}" tag will be expanded by "Code Embed" plugin.

7. Select "Custom Fields" in Options menu.
select Custom Fields

8. Add new Custom field.
Name:
CODEWebSDK
Value:
<script defer type="text/javascript" src="/wp/js/datasymbol-sdk-hlp.min.js"></script>
<script src='/wp/js/main.js'></script>
change "/wp/js/" path if you use else one

add new custom field to embed barode scanner in WordPress

9. Save the page/post.
11. [Web SDK] I am using barcode scanner WordPress plugin. How to insert barcode in input form field?
Using JavaScript you can pass a barcode to any element of your HTML page.

For example you have the following WordPress page

HTML input tag in WordPress

To insert barcode in the input tag with "barcodetxt" id just add the following code in WordPress Barcode Settings ("onBarcode JavaScript" field)

WordPress JavaScript code to insert barcode in input tag

12. [Web SDK] How to use barcode Web SDK with React.JS?
Below is the complete HTML code of the page with embeded JavaScript and React.JS code.
<html>
<head>  

<script>
</script>

<script src="https://unpkg.com/react@16/umd/react.development.js"></script>  
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>  
<script src="https://unpkg.com/This email address is being protected from spambots. You need JavaScript enabled to view it..0/babel.min.js"></script>
<script defer type="text/javascript" src="/js/datasymbol-sdk-hlp.min.js"></script> 

<script>
var DEF_WASM_PATH = '/js/datasymbol-sdk.wasm';

function onBarcodeReady (barcodeResult) {
	for (var i = 0; i < barcodeResult.length; ++i) {
	        var sBarcode = DSScanner.bin2String(barcodeResult[i]);
		DrawBarcodeObj.setBarcode( barcodeResult[i].type + ": " + sBarcode );
	}
};

function onError(err) {
    var statusElement = document.getElementById('status');
    statusElement.innerHTML = 'Error: ' + err.message;
}

function CreateScanner(){
    var scannerSettings = {
        scanner: {
            key: '',
            frameTimeout:	100,
            barcodeTimeout:	1000,
            beep: true,
        },
        viewport: {
            id: 'datasymbol-barcode-viewport',
            width: 500,
        },
        camera: {
            id: null,
            label: null,
            resx: 640,
            resy: 480,
            //facingMode: 'user', //'environment'
        },
        barcode: {
            barcodeTypes: ['EAN13', 'UPCA', 'Code128', 'DataMatrix', 'QRCode'],
            bQRCodeFindMicro: false,
        },
    };

    DSScanner.addEventListener('onError', onError);
    DSScanner.addEventListener('onBarcode', onBarcodeReady);

    DSScanner.addEventListener('onScannerReady', function () {
        console.log('HTML onScannerReady');
        var statusElement = document.getElementById('status');
        statusElement.innerHTML = ' ';	//statusElement.hidden = true;
        DSScanner.StartScanner();
    });

    DSScanner.Create(scannerSettings);
}

window.onload = function () {
	CreateScanner();
}

</script>

</head>  
<body>  
	<p id='status'>Downloading ...</p>
	<div id="datasymbol-barcode-viewport" style="display:block;width:640px;"></div>

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

	<script type="text/babel">

		class DrawBarcode extends React.Component {
			constructor() {
				super();
				window.DrawBarcodeObj = this;
				this.state = {barcode: ""};
			}

			render() {  
				return <p> {this.state.barcode} </p>;
			}

			setBarcode(sBarcode) {
				this.setState( {barcode: sBarcode} );
				console.log(sBarcode);
			}
		}

		ReactDOM.render(  
			<DrawBarcode />,
			document.getElementById("root")  
		);

	</script>  
</body>  
</html>


You can test it online here.
13. [Web SDK] How to redirect to the required URL in WordPress barcode scanner plugin?
Open the "Plugins" menu item in the WordPress administrator panel. In the "DataSymbol Barcode Scanner" plugin click "Settings". The settings page includes the "onBarcode JavaScript" field. You can write any JavaScript code in this field, and it will be executed after the barcode has been decoded. For instance, you can enter the following code:

redirect from WordPress barcode scanner to URL

if( barcodeResult.length > 0 ) {
	var sBarcode = DSScanner.bin2String(barcodeResult[0]);
	
	window.location.href = `https://websdk.datasymbol.com/wp/${sBarcode}`;
}

To be on the safe side, you can check the barcode length, its format (using a regular expression), or type (as shown below).
if( barcodeResult.length > 0 && barcodeResult[0].type == 'DataMatrix' ) {
	var sBarcode = DSScanner.bin2String(barcodeResult[0]);
	
	window.location.href = `https://websdk.datasymbol.com/wp/${sBarcode}`;
}

In this case, the redirect will be carried out only if the DataMatrix barcode is decoded.
14. [Web SDK] Beep sound doesn’t playback on iPhone/Safari.
I use your WordPress plugin for barcode scanning. Everything works all right in various browsers. However, the beep sound isn’t played back on iPhone after a barcode has been successfully scanned. How can I fix it?
The problem is that the iOS Safari browser requires prior interaction with the user to playback any sounds. We know a trick that helps bypass this requirement in the easiest way possible. iPhone users experience one inconvenience only when they scan the barcode — they have to click a button labeled, for example, "SCAN BARCODE".
OnLine demo here

The subtlety is that the CreateScanner method isn’t initiated right after users go to the barcode scanning page but after clicking the "SCAN" button. When the CreateScanner method is initiated, an unavailable (no URL specified) fake sound "plays back", and after that, a URL with the specific sound is installed. You have to playback the beep manually from the onBarcodeReady event.
var beepObj = null;
//...

function CreateScanner(){
	beepObj = new Audio("");
	beepObj.play();
	beepObj.src = "https://websdk.datasymbol.com/audio/beep1.mp3";
	//....
}

function onBarcodeReady (barcodeResult) {
	var bRed = false;

	for (var i = 0; i < barcodeResult.length; ++i) {
		if(barcodeResult[i].type == 'LinearUnrecognized' || barcodeResult[i].type == 'QRCodeUnrecognized' || barcodeResult[i].type == 'DataMatrixUnrecognized' || 
			barcodeResult[i].type == 'PDF417Unrecognized' || barcodeResult[i].type == 'AztecUnrecognized' || 
			!barcodeResult[i].barcodeAtPoint )
		{
			bRed = true;
			continue;
		}

        var sBarcode = DSScanner.bin2String(barcodeResult[i]);
		//...
	}

	if( bRed && barcodeResult.length == 1 )
		return;

	if( !bRed && barcodeResult.length > 0 )
		beepObj.play();
	//...
}


Using JavaScript, you can direct all users, except iPhone users, to scan the barcode immediately. iPhone users will still have to click the "SCAN" button.
15. [Web SDK] How to learn the subscription expiration date?
I have a one-year subscription to use your Web SDK. Can I somehow find out the subscription expiration date? We want to customize the subscription expiration notification.
You can do it simply by using the getLicenseInfo method.
16. [Web SDK] How can I automatically renew a One-Year Subscription?
We are currently using our one-year subscription. How can we automatically renew it after it has expired? We want to automate the process.
Everything described below applies to all licenses except "users per day".

Our Web SDK doesn’t use any Internet connection at all to decode or issue licenses. This approach allows you to maintain your security and confidentiality. That’s why the Web SDK subscription license is totally offline. You have to renew the license for your website manually.
Having purchased an annual subscription license for the first time, you get an Activation Key. Using this key, you generate a license for your specific domain. This license is valid for one year and additional 30 days to resolve any possible technical or payment issues.
You can renew your license manually as described here:
How to save the Web SDK key?

To renew the license automatically, you can write a script requesting the license info on our server. You can launch this script once after a one-year subscription expires. For instance, if you first purchased it on March 12, 2021, instruct the script to launch on March 14, 2022 (+2… 5 days to pay and update the key).

You can find the PHP script (updatekey.php) below.
<?php 
define( "URLREQ", "https://rkdsoft.com/gethidkey.php?tid=%s&hid=%s&sresp=0&lang=en" );
//your activation key
define( "ACTIVATION_KEY", "123-12345678-12345678" );
//your domain name
define( "DOMAIN_NAME", "yourdomain.com" );
//your path to the file with key
define( "KEY_FILE_NAME", "/home/mike/html/datasymbol.com/appupdatekey/keyfolder/key.txt" );

function errmsg($msg)
{
	mail( "This email address is being protected from spambots. You need JavaScript enabled to view it.", "my site key updating message", $msg, "From: This email address is being protected from spambots. You need JavaScript enabled to view it.\r\n");
	//print $msg;
}

//request key   
$resp = file_get_contents(sprintf(URLREQ, ACTIVATION_KEY, DOMAIN_NAME));

$exp = "/Error\\-(\\d{4})\\s+([\\sa-zA-Z\\/0-9\\+\\=]+)/m";

if( $resp && preg_match($exp, $resp, $matches) )
{
	//ok
	if( $matches[1] == "0000" )
	{
		if( file_put_contents( KEY_FILE_NAME, $matches[2] ) )
			errmsg( "ok" );
		else
			errmsg( "cannot save key" );
	}
	else
	//error
	{
		errmsg( sprintf("Error %s<br>%s",  $matches[1],  $matches[2]) );
	}
} 
else
{ 
    errmsg( "Key downloading failed." );
} 
?>

This script requests the license and saves it into the "key.txt" file. We assume you will save the key as shown here.

You can launch this script in Linux using the cron service. The line crontab launching the script is shown below.
0 0 14 3 * /usr/bin/php -f /home/mike/html/datasymbol.com/appupdatekey/updatekey.php

Note which user’s crontab you edit and in which user’s account this script will be launched. This particular user must have the authority to alter the "key.txt" file.
You can check the script and scheduled job correctness when you change the crontab date to the current one. When you call our server using your permanent domain name, the server will always award a license for you without any effect on activation instances, etc.
17. [Web SDK] The Web SDK fails to work correctly on some mobile devices.
We’ve tested your Web SDK on various mobile devices. It works perfectly fine. However, on some latest devices (for example, Samsung Galaxy s10, Huawei p30 Pro), it poorly scans even high-quality barcodes. Do you have any ideas on how to fix this malfunction?
Most likely, the problem is that the browser selects a wide-angle camera when you set facingMode to "environment". Various browsers may behave differently on the same device. One particular browser may select a conventional camera, while another will launch a wide-angle one.

Unfortunately, we are currently unaware of any documented way to select a non-wide-angle camera. We use the following code:
var camDevices=null;
var bDSMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);

//...

window.onload = function () {		
	//...
	
	DSScanner.getVideoDevices(function (devices) {
		devices.forEach(function (device) {
			console.log("device:" + device.label + '|' + device.id);
		});
		if(devices.length > 0) {
			camDevices = devices.slice();
			CreateScanner();
		}
		else {
			onError( {name: 'NotFoundError', message: ''} );
		}
	});
}

//...

//works for Chrome
function SelectBestCamera(camArr) {
	var _result = -1;
	var minCamIdx = 9999;
	for( var i=0; i < camArr.length; ++i ) {
		//find 'back' in camera label, and select min camera idx
		var matchArr = camArr[i].label.match(/[a-z0-9]+\s+(\d)+,.*(back).*/i);	//match "camera2 (0), facing (back), orie.."
		if( matchArr && matchArr.length == 3 && parseInt(matchArr[1]) < minCamIdx )
			_result = i;
	};

	return _result;
}

function CreateScanner() {
	//...

	if( camDevices && camDevices.length > 0 ) {
		if( bDSMobile ) {
			var camIdx = SelectBestCamera( camDevices );
			if( camIdx >= 0 )
				scannerSettings.camera.id = camDevices[camIdx].id;
			else
				scannerSettings.camera.facingMode = 'environment';
		}
		//non mobile, select first camera
		else {
			scannerSettings.camera.id = camDevices[0].id
			scannerSettings.camera.label = camDevices[0].label;
		}
	}

	//...
	
	DSScanner.Create( scannerSettings );	
}

The code searches the camera labeled "facing back". Then the camera with the smallest number is selected among the cameras found.
Besides, you can provide users with a list of available cameras and allow them to select the one they want.

Full code of our script (main.js).
18. [Web SDK] How to use Web SDK barcode scanner on the Angular platform?
I’m trying to use your Web SDK barcode scanner on the Angular platform. It fails to work. Have you got any examples?
You can see a short tutorial on how to use our Web SDK on the Angular platform below.

1.
Download "barcode-web-sdk-angular-proj.zip" file
Download

2.
Create new Angular project
> ng new HelloBarcode

copy the contents of the "barcode-web-sdk-angular-proj.zip" file to the HelloBarcode folder

3. start Angular project:
> cd HelloBarcode
> ng serve

Now, you can launch the browser and check how the project works.
http://localhost:4200


4. If you are creating your Angular project or modifying an existing one, pay attention to the following files.


"angular.json" ("build" and "test" nodes)
"assets": [
	"src/js/datasymbol-sdk.wasm"
],
"scripts": [
	"src/js/datasymbol.js", "src/js/datasymbol-sdk-hlp.min.js"
],
The "datasymbol-sdk.wasm" file is shown here because Angular saved this file while the project was built


"src/js/datasymbol.js"
var DEF_WASM_PATH = '/js/datasymbol-sdk.wasm';
If you want to place the wasm file in some other location different from the current folder, you have to define the "DEF_WASM_PATH" JavaScript variable.
Also using this file, you can alter various scanner settings, onBarcodeReady event, etc.


"src/app/barcodescanner.component.ts"
This file contains the barcode scanner component code itself.


"src/app/app.component.html"
includes "barcodescanner" tag
<barcodescanner></barcodescanner>


5. build Angular project:
> ng build
19. [Web SDK] How to use WebAssembly module (datasymbol-sdk.wasm) in "node.js" app?
The example below shows how to use our barcode decoder WebAssembly outside of Internet browser using only JavaScript.

The complete source code of this Node.js file you can download here.
Also you need to download "datasymbol-sdk.js" and "datasymbol-sdk.wasm" file.


const fs = require('fs');
const canvas = require('canvas');
const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;


//if .wasm file placed in not current folder
//var DEF_WASM_PATH = "/home/john/Desktop/nodejs/datasymbol-sdk.wasm";

var Module = {
	decHandle: 0,

	locateFile: function (fName) {
		if ((fName == 'datasymbol-sdk.wasm') && (typeof DEF_WASM_PATH !== 'undefined'))
			return DEF_WASM_PATH;
		return fName;
	},
	onDataSymbolWASMReady: function (hDecoder) {
		decHandle = hDecoder;
		DecodeImageFile("/home/john/Desktop/nodejs/linear-4.jpg");
	},
	onRuntimeInitialized: function () {
		Module.ccall('InitLib', 'number', ['array'], [str2AsciiArr("")] );
	},
	onAbort: function () {
		console.log("onModuleAbort");
	},
};


// include JS file
eval(fs.readFileSync('datasymbol-sdk.js')+'');


function str2AsciiArr(str) {
	var byteStr = new Uint8Array(str.length + 1);
	for (var i = 0; i < str.length; ++i) {
		var charCode = str.charCodeAt(i);
		if (charCode <= 0xFF)
			byteStr[i] = charCode;
	}
	byteStr[i] = 0x00;
	return byteStr;
}

function SetProperty(decHandle, propName, propVal) {
	return Module.ccall('setProperty',
			'number',
			['number', 'array', 'array'],
			[decHandle, str2AsciiArr(propName), new Uint8Array(new Uint32Array([propVal]).buffer)]);
}


function DecodeFrame(decHandle, pFrameBuf, width, height) {
	//decode and collect barcodes in "barcodeResult"
	var barcodeResult = [];
	var res = _DecodeRGBA(decHandle, pFrameBuf, width, height);
	var bufLen = width * height * 4;
	if (res == 0) {
		var numBarodes = _getResNum(decHandle);

		for (var i = 0; i < numBarodes; ++i) {
			var barcode = {};
			var dataLen = _getResData(decHandle, pFrameBuf, bufLen, i);
			if (dataLen >= 0) {
				//barcode data
				barcode.data = [];
				for (var j = 0; j < dataLen; j++)
					barcode.data.push(Module.HEAPU8[pFrameBuf + j]);

				//collect points
				barcode.points = [];
				res = _getResPoints(decHandle, pFrameBuf, bufLen, i);
				for (var j = 0; j < 4; j++)
					barcode.points.push( { x: Module.getValue(pFrameBuf + j * 8, 'i32'), y: Module.getValue(pFrameBuf + j * 8 + 4, 'i32') } );

				//type
				barcode.bt = _getResBarcodeType(decHandle, i);

				barcodeResult.push(barcode);
			}
		}
	}

	return barcodeResult;
}

function DecodeImageFile(imageSrc) {
	//read image file
	const fileData = fs.readFileSync(imageSrc, {flag:'r'});
	var img = new canvas.Image();
	img.src = fileData;

	//draw image into the canvas and get RGBA data
	var cnv = new canvas.Canvas(img.width, img.height);   
	var ctx = cnv.getContext('2d');
	ctx.drawImage(img, 0, 0, img.width, img.height);
	var imageData = ctx.getImageData(0, 0, img.width, img.height);

	//set any barcode reader properties
	var res = SetProperty(decHandle, 'uiLinearFindBarcodes', 4);

	//allocate frame buffer
	var bufLen = img.width * img.height * 4;
	var pFrameBuf = _malloc(bufLen);

	//decode frame
	for( var i=1; i <= 3; ++i ) {
		console.log(i + ':');

		Module.HEAPU8.set(imageData.data, pFrameBuf);
		var barcodeResult = DecodeFrame(decHandle, pFrameBuf, img.width, img.height);

		//print result
		console.log('Decoded: ' + barcodeResult.length);
		for( var n=0; n < barcodeResult.length; ++n )
			console.log( String.fromCharCode.apply(null, barcodeResult[n].data) );

		console.log('');
	}

	//free resources
	_FreeLib(decHandle);
	if (pFrameBuf)
		_free(pFrameBuf);
}



1. [BarcodeScanner. Windows] How to use BarcodeScanner app with Python?
We use your Barcode Scanner as "Barcode Scanner Automation". It's possible to send us a code example that allows to handle decoded Barcodes with a Python script ?
Please see the following Python code.
[Python]
import win32com.client  #https://sourceforge.net/projects/pywin32/
import pythoncom
import time

class EvHandler:
    def OnBarcodeIn(self, _1):
        print(_1);

scanner = win32com.client.DispatchWithEvents("BarcodeScanner.Reader", EvHandler)
scanner.Visible = True

while 1:
    pythoncom.PumpWaitingMessages() 
    time.sleep(0.8) # Don't use up all our CPU checking constantly
2. [BarcodeScanner. Windows] How to use "Execute Command" settings
Using this feature you can start any your Windows application and pass barcode data. Use #BARCODE# tag in place where you need to have decoded barcode.

Example 1.
if you have the following settings

Save decoded barcode in file using windows batch file. Barcode Reader Windows Scanner app

content of c:\1\b.bat file:
@echo off
@echo %1> c:\1\barcode.txt
or
@echo off
echo %1 > c:\1\temp.txt
type c:\1\temp.txt >> c:\1\barcode.txt
del c:\1\temp.txt
If the Scanner decodes the barcode, the "b.bat" will be started with barcode parameter. The above batch file saves barcode in "barcode.txt"


Example 2.

suppose you have the following QR barcode (with encoded "c:\1\b.xlsx" inside):
Start excel file from barcode data. Barcode Reader Windows Scanner app

if you have the following setting, scanner will open Excel "c:\1\b.xls" file
Setings for open Excel file. Barcode Reader Windows Scanner app

			
3. [BarcodeScanner. Windows] How to catch barcode in Excel (not using keyboard wedge)?
You can use the following Excel Macros. Open VBA editor (Alt + F11), click "This Workbook" and insert the following code.

Dim WithEvents BarScanner As BarcodeScannerLib.Reader

Private Sub Workbook_Open()
    Set BarScanner = CreateObject("BarcodeScanner.Reader")
    BarScanner.Visible = True
End Sub

Private Sub BarScanner_BarcodeIn(ByVal barcode As String)
    'MsgBox barcode
    ActiveWindow.ActiveCell.Value = barcode
    ActiveWindow.ActiveCell.Offset(1, 0).Range("A1").Select
End Sub


Add reference to our Barcode Scanner application (menu Tools - References...)

Excel VBA reference for DataSymbol Barcode Scanner Application

You can disable barcode keyboard transferring to avoid unwanted behaviour (in Barcode Scanner Settings - Program Tab - "Transfer Barcode in keyboard").
4. [BarcodeScanner. Raspberry (dsreader)] dsreader for Raspberry Pi is console app, how to get barcode from it?
you have several ways

1. you can redirect output of dsreader app in any other application
# ./dsreader | sed 's/Hello/77/g'
here is "sed" is only for example, instead "sed" you can use your own program

2. you can connect to dsreader using TCP/IP, for example
# ./dsreader -d -p 1234
# telnet localhost 1234
write your own application (instead telnet) for TCP/IP connection
5. [BarcodeScanner. Windows] "Find what" with regular expression
You can use regular expression to replace some parts of decoded barcode.

for example

using regular expression for replace scanned barcode parts

this regular expression finds "1E" (hexadecimal value) or "1D" (hexadecimal value) or "r" or "hello" 
in decoded barcode and replace by "#"
			
Supports:
Linear: Interleaved 2/5, Industrial 2/5, Code 39, Code 39 Extended, Codabar, Code 11, Code 128, Code 128 Extended, EAN/UCC 128, UPC-E, UPC-A, EAN-8, EAN-13, Code 93, Code 93 Extended, DataBar Omnidirectional (RSS-14), DataBar Truncated (RSS-14 Truncated), DataBar Limited (RSS Limited), DataBar Stacked, DataBar Expanded, DataBar Expanded Stacked.
2D: PDF417 (Compact, Micro), QRCode (Micro), DataMatrix, Aztec Code
Platforms:
Windows 32 & 64, 10(UWP), Phone 8/8.1/10,Windows Mobile, Android, Linux, Raspberry Pi, MacOS, iPhone