DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

David has posted 81 posts at DZone. View Full User Profile

How to Recognize Text in Photos on Android Device Using Aspose.OCR

06.25.2014
| 538 views |
  • submit to reddit
//MainActivity.java

public class MainActivity extends ActionBarActivity {
  // ...

  protected static final int REQUEST_IMAGE_CAPTURE = 1;
  File tmpfile;

  public void captureImage(View view) {
    Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (i.resolveActivity(getPackageManager()) != null) {
    try {
      tmpfile = File.createTempFile("Photo", ".jpg",
          Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
    } catch (IOException x) {
      // We are lost :)
      throw new RuntimeException(x);
    }
    i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tmpfile));
    startActivityForResult(i, REQUEST_IMAGE_CAPTURE);
    }
  }
  
  // ...

}

//We don't know when the camera activity will complete and our application will resume its normal operation. So we shall wait and listen to the results in background. Android provides onActivityResult method for this purpose. We shall add it to our MainActivity class as specified in Android documentation.

//MainActivity.java

public class MainActivity extends ActionBarActivity {

  // ...

  @Override
  protected void onActivityResult(int request, int result, Intent data) {
    if (request == REQUEST_IMAGE_CAPTURE && result == RESULT_OK) {
      if (tmpfile == null) {
        Log.e("onActivityResult", "Photo was not saved. Doing nothing");
        return;
      }

      new OcrTask().execute(tmpfile);
      displayTextResults("Uploading photo and recognizing text. This may take a few seconds.");
    }
  }

  // ...

}

//Here in onActivityResult we have used REQUEST_IMAGE_CAPTURE and tmpfile from captureImage. We also have used OcrTask and displayTextResults, which are our next topic.

//MainActivity.java

public class MainActivity extends ActionBarActivity {
  // ...
  public class OcrTask extends AsyncTask<File, Void, String> {
    String requestUrl;
    String appSID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
    String appKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

    @Override
    protected void onPreExecute() {
      super.onPreExecute();
	  // Our implementation goes here...
	}

    @Override
    protected String doInBackground(File... params) {
      // Our implementation goes here...
    }

    @Override
    protected void onPostExecute(String result) {
      super.onPostExecute(result);
      // Our implementation goes here...
    }
  }
}

//We have three methods here. onPreExecute is called before the asynchronous operation is started. It has no parameters. We perform some initial operation in here and prepare a signed request URL. A signed URL means to make sure that we are authorized to make that API call. We require appSID and appKey for this purpose which can be obtained by signing up for free at http://cloud.aspose.com/.

//OcrTask.onPreExecute

@Override
protected void onPreExecute() {
  super.onPreExecute();

  requestUrl = "https://api.aspose.com/v1.1/ocr/recognize?appSID=" + appSID;
  try {
    Mac mac = Mac.getInstance("HmacSHA1");
    mac.init(new SecretKeySpec(appKey.getBytes(), "HmacSHA1"));
    mac.update(requestUrl.getBytes());
    String signature = Base64.encodeToString(mac.doFinal(), Base64.NO_PADDING);
    requestUrl += "&signature=" + signature;

    Log.i("onPreExecute", "Signed request URL: " + requestUrl);
  } catch (Exception x) {
    throw new RuntimeException(x);
  }
}

//The doInBackground will do the actual API call. We are using HttpUrlConnection as Http client. We shall upload our captured image file. The returned response is in JSON format and HTTP request method is POST. So we shall setup the connection parameters accordingly.

//OcrTask.doInBackground

@Override
protected String doInBackground(File... params) {
  File file = params[0];
  HttpURLConnection connection = null;
  try {
    FileInputStream fstream = new FileInputStream(file);
    int fsize = fstream.available();

    connection = (HttpURLConnection) new URL(requestUrl).openConnection();
    connection.setRequestMethod("POST");
    connection.setDoOutput(true);
    connection.setRequestProperty("Accept", "application/json");
    connection.setRequestProperty("Content-Length", String.valueOf(fsize));

    OutputStream upload = connection.getOutputStream();
    byte[] buffer = new byte[10240];
    int len;
    while ((len = fstream.read(buffer)) != -1) {
      upload.write(buffer, 0, len);
    }
    upload.close();
    fstream.close();

    InputStream i = connection.getInputStream();
    String text = new Scanner(i).useDelimiter("\\A").next();
    i.close();

    //file.delete();
    Log.i("doInBackground", text);
    return text;
  } catch (FileNotFoundException fnfx) {
    InputStream e = connection.getErrorStream();
    String text = new Scanner(e).useDelimiter("\\A").next();

    Log.i("doInBackground", text);
    return text;
  } catch (Exception x) {
    throw new RuntimeException(x);
  }
}

//After we have retrieved the results from Aspose.Ocr for Cloud API, we need a little bit manipulation. As the response is JSON, should now read the recognized text and also check for error, if any. We shall do the manipulation in onPostExecute method.

//OcrTask.onPostExecute

@Override
protected void onPostExecute(String result) {
  super.onPostExecute(result);

  String text = "";
  try {
    JSONObject json = new JSONObject(result);
    if (json.has("Status") && json.getString("Status").equals("OK")) {
      text = json.getString("Text");
    } else if (json.has("Message")) {
      text = "Error: " + json.getString("Message");
    }
  } catch (JSONException x) {
    throw new RuntimeException(x);
  }

  displayTextResults(text);
}

//Now comes the simplest and yet important part of our application i.e. display the recognized text results. 

//MainActivity.java

public class MainActivity extends ActionBarActivity {
  // ...

  public void displayTextResults(String text) {
    TextView t = (TextView) findViewById(R.id.text_results);
    t.setText(text);
  }

  // ...
}
This tutorial shows how developers can recognize text in photos on Android device using Aspose.Ocr for Cloud. We shall use the device camera to capture a photo and use the Aspose API to recognize the text. The user will able be to copy the recognized text and paste it into any other application like an email or a text message. You will need the following:

  • Android Developer Tools (ADT)
  • Aspose.Ocr for Cloud

Our code has four major parts.

  • captureImage Send request to camera to capture photo and save it on external device
  • onActivityResult Receive results from camera when our photo is ready.
  • OcrTask Perform API operation for us
  • displayTextResults Display OCR results

We shall implement each portion of our code step-by-step and explain it. Let's start with captureImage. As we can see in previous section, captureImage is the onClick handler of our Take Photo button. So the method signature must follow Android specifications: