Create a barcode reader using HTML5, JavaScript, and Jetty

Updated in 2021:

  1. The Dynamsoft Barcode Reader now has a client-side JavaScript SDK which makes it possible to read barcodes from within the browser. Learn about the JavaScript SDK
  2. The Dynamsoft Barcode Reader now has mobile native SDKs supporting Android and iOS.
  3. The Dynamsoft Barcode Reader now has an official Java SDK.
  4. The article and the code in the GitHub repo is revamped to use the official Java SDK and support the latest APIs and browsers.

This article talks about creating a HTML5 barcode reader using websocket in Java, which is inspired by the article[^1]. We can transmit the real-time camera stream to a remote server using HTML5 in Web browsers and decode the barcode image with Dynamsoft Barcode Reader SDK on the server that running on Windows, Linux or Mac.

If you would like to scan barcodes and QR codes at the client side of a browser, please read blog: Build a Barcode and QR Code Scanner Using JavaScript and HTML5


  • Dynamsoft Barcode Reader: Java SDK - available for Windows, Linux and Mac.
  • WebSocket Server: Embedded Jetty - a Java HTTP (Web) Server and Java Servlet container.

How to Open Webcam or Mobile Cameras with HTML5

In HTML5, MediaDevices.getUserMedia() prompts the user for camera permission. Here we use it to show the camera video stream:

if (navigator.mediaDevices.getUserMedia) {
    navigator.mediaDevices.getUserMedia(constraints).then(function(mediaStream) {
        try {
            videoElement.srcObject = mediaStream;
        catch (error) {
            videoElement.src = window.URL.createObjectURL(mediaStream);
        .catch(function(error) {
            console.log( + ": " + error.message);
else {
    console.log("MediaDevices.getUserMedia not supported");

Camera Preview Data for Transmission

When using Webcam or cameras in Web browsers, we can capture preview image as base64 String and then convert it to binary:

Convert canvas to base64 String:

data = canvas.toDataURL('image/png', 1.0);

Convert base64 to binary:

// stackoverflow:
function dataURItoBlob(dataURI) {
    // convert base64/URLEncoded data component to raw binary data held in a string
    var byteString;
    if (dataURI.split(',')[0].indexOf('base64') >= 0)
        byteString = atob(dataURI.split(',')[1]);
        byteString = unescape(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to a typed array
    var ia = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);

    return new Blob([ia], {type:mimeString});

// convert base64 to binary
newblob = dataURItoBlob(data);

We can wrap received binary data as BufferedImage on server-side:

ByteArrayInputStream in = new ByteArrayInputStream(data);
BufferedImage bi;
try {
    bi =;
    File file = new File(mFile);
    // save client data to local image file
    ImageIO.write(bi, "PNG", file);

} catch (IOException e1) {
    // TODO Auto-generated catch block

How to Use WebSocket to Send and Receive Data

WebSocket Client in JavaScript

Create WebSocket:

// create websocket
var ws = new WebSocket("wss://");

ws.onopen = function() {


ws.onmessage = function (evt) {


ws.onclose = function() {


ws.onerror = function(err) {


Set an interval time for sending camera stream:

// scan barcode
function scanBarcode() {
  intervalId = window.setInterval(function() {
    if (!isConnected || isPaused) {

    var data = null, newblob = null;

    ctx.drawImage(videoElement, 0, 0, videoWidth, videoHeight);
    // convert canvas to base64
    data = canvas.toDataURL('image/png', 1.0);
    // convert base64 to binary
    newblob = dataURItoBlob(data);

  }, 200);
  console.log("create id: " + intervalId);

Do not forget to empty interval events if you stop scanning barcode:


WebSocket Server in Java

Create the server. Since the getUserMedia API requires HTTPS, we need to enable HTTPS. Please note that on iOS, self-signed certs do NOT work for secure websocket connections.

public class WebSocketServer {

    public static void main(String[] args) throws Exception {
        Server server = new Server();
        //Set static folder
        File f = new File("www");
        ServletContextHandler context = new ServletContextHandler(
        context.setWelcomeFiles(new String[] { "index.html" });

        ServletHolder holderPwd = new ServletHolder("default",
        holderPwd.setInitParameter("dirAllowed", "true");
        context.addServlet(holderPwd, "/");
        //Configure handlers with HTTPS support
        HandlerCollection handlerList = new HandlerCollection();
        handlerList.setHandlers(new Handler[]{new WSHandler(),context});
        HttpConfiguration http_config = new HttpConfiguration();

        HttpConfiguration https_config = new HttpConfiguration(http_config);
        https_config.addCustomizer(new SecureRequestCustomizer());
        SslContextFactory sslContextFactory = new SslContextFactory();
        // You can congifure your own key. See

        ServerConnector wsConnector = new ServerConnector(server);

        ServerConnector wssConnector = new ServerConnector(server,
                new SslConnectionFactory(sslContextFactory,
                new HttpConnectionFactory(https_config)); // THIS WAS MISSING


Configure policies:

public class WSHandler extends WebSocketHandler {

    public void configure(WebSocketServletFactory factory) {
        // TODO Auto-generated method stub
        factory.setCreator(new BarcodeCreator());

        // configuration
        factory.getPolicy().setMaxBinaryMessageBufferSize(1024 \* 1024);
        factory.getPolicy().setMaxTextMessageBufferSize(1024 \* 1024);
        factory.getPolicy().setMaxTextMessageSize(1024 \* 1024);
        factory.getPolicy().setMaxBinaryMessageSize(1024 \* 1024);

Create WebSocket:

public class BarcodeSocket {

    public void onClose(int statusCode, String reason) {


    public void onError(Throwable t) {


    public void onConnect(Session session) {


    public void onMessage(byte[] data, int off, int len) {
        //receive video frame, decode and send decoded results to the client


public class BarcodeCreator implements WebSocketCreator {

    public Object createWebSocket(ServletUpgradeRequest arg0, ServletUpgradeResponse arg1) {
        // TODO Auto-generated method stub
        return new BarcodeSocket();


How to Read Barcode in Java with Dynamsoft Barcode Reader SDK

With the Java SDK, we can read barcodes with a few lines of code:

private BarcodeReader dbr;
public BarcodeSocket() {
    try {
        dbr = new BarcodeReader();
    } catch (BarcodeReaderException e) {
        // TODO Auto-generated catch block
private String readBarcode(String fileName) {
    StringBuilder sb = new StringBuilder();
    TextResult[] results = null;
    try {
        results = dbr.decodeFile(fileName, "");
    } catch (BarcodeReaderException e) {
        // TODO Auto-generated catch block
    for (TextResult result : results) {
        sb.append("Value: ");
    return sb.toString();

Testing HTML5 Barcode Reader in Chrome for Android and Windows

Chrome for Android

mobile android camera

mobile barcode reader

Chrome for Windows

desktop barcode reader

Source Code