‚Äč

Cloud OCR SDK Documentation

Barcode reader in Java: How to create barcode scanner in ABBYY Cloud OCR SDK

Creating a barcode reader in Java is very simple with ABBYY Cloud OCR SDK. What do you need to do?

  1. Register, if you are not a registered user of Cloud OCR SDK. During registration you obtain Application ID and Application Password for accessing Web API of Cloud OCR SDK. Cloud OCR server requires the Application ID and Application Password to be provided with each request.
  2. After you have registered, select the processing method, which should be used for barcode reading:
  3. Call the selected method with necessary parameters. You can find information on how to tune the parameters of processing in How to Recognize Barcodes. Pass the Application ID and Application Password with the request.
  4. Receive a response in XML format from the server. A successful response will contain the ID of the created task. Use this ID to monitor the status of the request. Monitoring is performed using the getTaskStatus method.
  5. Download the result of processing by the reference provided in the response after the request is completed (it has the Completed status).

See details on handling requests in How to Work with Cloud OCR SDK.

Below you can find implementations of this procedure in Java. The sample code extracts barcodes from an image and saves results in an XML file.

import com.abbyy.ocrsdk.*;

public class TestApp {

  /**
  * @param args
  */
  public static void main(String[] args) {
    System.out.println( "App started" );

    // The application takes as input parameters:
    // - Application ID
    // - Application Password
    // - Path to the image file to be recognized
    // - Path to the file to save recognized values to
    // Application ID and Application Password can be created 
    // by a registered user. To do it, 
    // log in to the ABBYY Cloud OCR SDK web site.
    // If you are not registered yet, register 
    // at http://cloud.ocrsdk.com/Account/Register
if( args.length != 4 ) { System.out.println( "Invalid arguments. Usage:" ); System.out.println( "program <app id> <password> <input file> <output file>" ); return; } // See implementation of the Client class below. Client restClient = new Client(); restClient.ApplicationId = args[0]; restClient.Password = args[1]; String filePath = args[2]; String outputFile = args[3]; try { System.out.println( "Uploading.." ); // To extract barcode values from an image, // send an image to Cloud OCR server using processImage call // with barcodeRecognition profile as a parameter. Task task = restClient.ProcessImage(filePath); // See implementation of the Task class below. // To read a single barcode field, // send an image of a barcode to Cloud OCR server // using processBarcodeField call: // Task task = restClient.ProcessBarcodeField(filePath); // See implementation of the Task class below. while( task.IsTaskActive() ) { Thread.sleep(2000); System.out.println( "Waiting.." ); task = restClient.GetTaskStatus(task.Id); } if( task.Status == Task.TaskStatus.Completed ) { System.out.println( "Downloading.." ); restClient.DownloadResult(task, outputFile); } else { System.out.println( "Task failed" ); } // Parse output XML to extract barcode values. // Note that output XML files have different structure // depending on the method you used for processing. System.out.println( "Ready" ); } catch( Exception e) { System.out.println( "Exception occurred:" + e.getMessage() ); } } }

The implementation of the Client class, used in the example above:

package com.abbyy.ocrsdk;

import java.io.*;
import java.net.*;

public class Client {
  public String ApplicationId;
  public String Password;

  public String ServerUrl = "http://cloud.ocrsdk.com";

  public Task ProcessImage( String filePath) throws Exception
  {
    // Use barcodeRecognition profile to extract barcode values
    // Save results in XML (you can use any other available output format).
    // For details, see API Reference for processImage method.
    URL url = new URL(ServerUrl + "/processImage?profile=barcodeRecognition&exportFormat=xml");
    byte[] fileContents = readDataFromFile( filePath );

    HttpURLConnection connection = openPostConnection(url);

    connection.setRequestProperty("Content-Length", 
      Integer.toString(fileContents.length));
    connection.getOutputStream().write( fileContents );

    BufferedReader reader = new BufferedReader( new InputStreamReader( connection.getInputStream()));
    return new Task(reader);
  }

  public Task ProcessBarcodeField( String filePath) throws Exception
  {
    // Specify the region of a barcode (by default, the whole image is recognized), 
    // barcode type, and other parameters.
    // For details, see API Reference for processBarcodeField method.
    URL url = new URL(ServerUrl + "/processBarcodeField?region=0,0,100,100&barcodeType=pdf417");
    byte[] fileContents = readDataFromFile( filePath );

    HttpURLConnection connection = openPostConnection(url);

    connection.setRequestProperty("Content-Length", 
      Integer.toString(fileContents.length));
    connection.getOutputStream().write( fileContents );

    BufferedReader reader = new BufferedReader( new InputStreamReader( connection.getInputStream()));
    return new Task(reader);
  }

  public Task GetTaskStatus( String taskId ) throws Exception
  {
    URL url = new URL( ServerUrl + "/getTaskStatus?taskId=" + taskId );

    URLConnection connection = openGetConnection( url );
    BufferedReader reader = new BufferedReader( new InputStreamReader( connection.getInputStream()));
    return new Task(reader);
  }

  public void DownloadResult( Task task, String outputFile ) throws Exception
  {
    if( task.Status != Task.TaskStatus.Completed ) {
      throw new IllegalArgumentException("Invalid task status");
    }

    if( task.DownloadUrl == null ) {
      throw new IllegalArgumentException( "Cannot download result without url" );
    }

    URL url = new URL( task.DownloadUrl );
    URLConnection connection = url.openConnection(); // do not use authenticated connection

    BufferedInputStream reader = new BufferedInputStream( connection.getInputStream());

    FileOutputStream out = new FileOutputStream(outputFile);

    byte data[] = new byte[1024];
    int count;
    while ((count = reader.read(data, 0, 1024)) != -1)
    {
      out.write(data, 0, count);
    }
  }

  private HttpURLConnection openPostConnection( URL url ) throws Exception
  {
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setDoOutput(true);
    connection.setDoInput(true);
    connection.setRequestMethod("POST");
    setupAuthorization( connection );
    connection.setRequestProperty("Content-Type", "applicaton/octet-stream" );

    return connection;
  }

  private URLConnection openGetConnection( URL url ) throws Exception
  {
    URLConnection connection = url.openConnection();
    setupAuthorization( connection );
    return connection;
  }

  private void setupAuthorization( URLConnection connection )
  {
    connection.addRequestProperty( "Authorization", "Basic: " + encodeUserPassword()); 
  }

  private byte[] readDataFromFile( String filePath ) throws Exception
  {
    File file = new File( filePath );
    InputStream inputStream = new FileInputStream( file );
    long fileLength = file.length();
    byte[] dataBuffer = new byte[(int)fileLength];

    int offset = 0;
    int numRead = 0;
    while( true ) {
      if( offset >= dataBuffer.length ) {
        break;
      }
      numRead = inputStream.read( dataBuffer, offset, dataBuffer.length - offset );
      if( numRead < 0 ) {
        break;
      }
      offset += numRead;
    }
    if( offset < dataBuffer.length ) {
      throw new IOException( "Could not completely read file " + file.getName() );
    }
    return dataBuffer;
  }

  private String encodeUserPassword()
  {
    String toEncode = ApplicationId + ":" + Password;
    return Base64.encode( toEncode );
  }

}

The implementation of the Task class:

package com.abbyy.ocrsdk;

import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import org.xml.sax.*;

public class Task {
  public enum TaskStatus {
    Unknown, 
    Submitted, 
    Queued, 
    InProgress, 
    Completed, 
    ProcessingFailed, 
    Deleted, 
    NotEnoughCredits 
  }

  public Task( Reader reader ) throws Exception
  {
    // Read full task information from xml
    InputSource source = new InputSource();
    source.setCharacterStream(reader);
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document doc = builder.parse(source);

    NodeList taskNodes = doc.getElementsByTagName("task");
    Element task = (Element)taskNodes.item(0);

    parseTask(task);
  }

  public TaskStatus Status = TaskStatus.Unknown;
  public String Id;
  public String DownloadUrl;

  public Boolean IsTaskActive()
  {
    if( Status == TaskStatus.Queued || Status == TaskStatus.InProgress )
      return true;

    return false;
  }

  private void parseTask( Element taskElement )
  {
    Id = taskElement.getAttribute("id");
    Status = parseTaskStatus( taskElement.getAttribute( "status" ) );
    if( Status == TaskStatus.Completed )
      DownloadUrl = taskElement.getAttribute("resultUrl");
  }

  private TaskStatus parseTaskStatus( String status )
  {
    if( status.equals( "Submitted") )
      return TaskStatus.Submitted;
    else if( status.equals( "Queued" ) )
      return TaskStatus.Queued;
    else if( status.equals( "InProgress" ) )
      return TaskStatus.InProgress;
    else if( status.equals( "Completed") )
      return TaskStatus.Completed;
    else if (status.equals( "ProcessingFailed") )
      return TaskStatus.ProcessingFailed;
    else if (status.equals( "Deleted") )
      return TaskStatus.Deleted;
    else if (status.equals( "NotEnoughCredits") )
      return TaskStatus.NotEnoughCredits;
    else
      return TaskStatus.Unknown;
  }

}

You can also find this barcode reader code in Java at the code samples provided with ABBYY Cloud OCR SDK.