/ocr/textscanner/src/com/google/marvin/textscanner/ScannerActivity.java

http://eyes-free.googlecode.com/ · Java · 299 lines · 221 code · 49 blank · 29 comment · 37 complexity · 677b717d6657959130e1a70234fe3589 MD5 · raw file

  1. /*
  2. * Copyright (C) 2009 Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.google.marvin.textscanner;
  17. import android.app.Activity;
  18. import android.content.Context;
  19. import android.content.Intent;
  20. import android.content.SharedPreferences;
  21. import android.os.Bundle;
  22. import android.os.Parcelable;
  23. import android.preference.PreferenceManager;
  24. import android.text.ClipboardManager;
  25. import android.text.Editable;
  26. import android.util.Log;
  27. import android.view.Menu;
  28. import android.view.MenuItem;
  29. import android.view.View;
  30. import android.view.Window;
  31. import android.view.WindowManager;
  32. import android.view.View.OnClickListener;
  33. import android.widget.Button;
  34. import android.widget.EditText;
  35. import android.widget.Toast;
  36. import com.android.ocr.client.Config;
  37. import com.android.ocr.client.Intents;
  38. import com.android.ocr.client.Ocr;
  39. import com.android.ocr.client.Result;
  40. import java.util.Set;
  41. /**
  42. * Demonstration application for using Intents. Can load text from the camera
  43. * and copy it to the clipboard.
  44. *
  45. * @author alanv@google.com (Alan Viverette)
  46. */
  47. public class ScannerActivity extends Activity implements OnClickListener {
  48. private static final String TAG = "ScannerActivity";
  49. private static final int REQUEST_CAPTURE = 0;
  50. private static final int REQUEST_RECOGNIZE = 1;
  51. private static final int PREFS_ID = Menu.FIRST;
  52. private Ocr mOcr;
  53. @Override
  54. public void onCreate(Bundle savedInstanceState) {
  55. Log.i(TAG, "Creating ScannerActivity...");
  56. super.onCreate(savedInstanceState);
  57. setContentView(R.layout.main);
  58. Window window = getWindow();
  59. window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  60. final Button capture = (Button) findViewById(R.id.capture);
  61. capture.setEnabled(false);
  62. Button clipboard = (Button) findViewById(R.id.clipboard);
  63. View.OnClickListener onCapture = new View.OnClickListener() {
  64. @Override
  65. public void onClick(View v) {
  66. requestCapture();
  67. }
  68. };
  69. Ocr.InitCallback onInit = new Ocr.InitCallback() {
  70. @Override
  71. public void onInitialized(int status) {
  72. switch (status) {
  73. case Ocr.STATUS_SUCCESS: {
  74. capture.setEnabled(true);
  75. break;
  76. }
  77. case Ocr.STATUS_MISSING:
  78. case Ocr.STATUS_FAILURE: {
  79. finish();
  80. break;
  81. }
  82. }
  83. }
  84. };
  85. // Load OCR library in this Activity so that we don't have to
  86. // start & stop the service every time we open RecognizeActivity
  87. mOcr = new Ocr(this, onInit);
  88. capture.setOnClickListener(onCapture);
  89. clipboard.setOnClickListener(this);
  90. }
  91. @Override
  92. protected void onDestroy() {
  93. mOcr.release();
  94. super.onDestroy();
  95. }
  96. @Override
  97. public boolean onCreateOptionsMenu(Menu menu) {
  98. super.onCreateOptionsMenu(menu);
  99. menu.add(0, PREFS_ID, 0, R.string.menu_prefs);
  100. return true;
  101. }
  102. @Override
  103. public boolean onOptionsItemSelected(MenuItem item) {
  104. switch (item.getItemId()) {
  105. case PREFS_ID: {
  106. Intent intent = new Intent(this, PrefsActivity.class);
  107. startActivity(intent);
  108. break;
  109. }
  110. }
  111. return super.onOptionsItemSelected(item);
  112. }
  113. public void requestCapture() {
  114. SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
  115. String resolution = prefs.getString(PrefsActivity.RESOLUTION, PrefsActivity.DEFAULT_RESOLUTION);
  116. Intent capture = new Intent(Intents.Capture.ACTION);
  117. if (resolution != null) {
  118. String[] values = resolution.split("x");
  119. int width = Integer.parseInt(values[0]);
  120. int height = Integer.parseInt(values[1]);
  121. capture.putExtra(Intents.Capture.WIDTH, width);
  122. capture.putExtra(Intents.Capture.HEIGHT, height);
  123. }
  124. startActivityForResult(capture, REQUEST_CAPTURE);
  125. }
  126. public void requestRecognize(Intent data) {
  127. Parcelable extra = data.getParcelableExtra(Intents.Capture.CONFIG);
  128. if (!(extra instanceof Config)) {
  129. Log.e(TAG, "requestRecognize received wrong parcelable type (was " + extra + ")");
  130. return;
  131. }
  132. SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
  133. Config config = (Config) extra;
  134. config.pageSegMode = Config.PSM_AUTO;
  135. config.language = prefs.getString(PrefsActivity.LANGUAGE, PrefsActivity.DEFAULT_LANGUAGE);
  136. config.debug = prefs.getBoolean(PrefsActivity.DEBUG, PrefsActivity.DEFAULT_DEBUG);
  137. boolean textdetect =
  138. prefs.getBoolean(PrefsActivity.TEXTDETECT, PrefsActivity.DEFAULT_TEXTDETECT);
  139. if (textdetect) {
  140. config.options |= Config.OPT_DETECT_TEXT;
  141. }
  142. boolean normalize = prefs.getBoolean(PrefsActivity.NORMALIZE, PrefsActivity.DEFAULT_NORMALIZE);
  143. if (normalize) {
  144. config.options |= Config.OPT_NORMALIZE_BG;
  145. }
  146. if (config.image != null) {
  147. Intent recognize = new Intent(Intents.Recognize.ACTION);
  148. recognize.putExtra(Intents.Recognize.CONFIG, config);
  149. startActivityForResult(recognize, REQUEST_RECOGNIZE);
  150. } else {
  151. Log.e(TAG, "requestRecognize received null image");
  152. }
  153. }
  154. public void handleCompleted(Intent data) {
  155. if (!data.hasExtra(Intents.Recognize.RESULTS)) {
  156. Log.e(TAG, "handleCompleted received empty intent");
  157. Set<String> keys = data.getExtras().keySet();
  158. for (String key : keys) {
  159. Log.e(TAG, " Contains '" + key + "'");
  160. }
  161. }
  162. Parcelable[] results = data.getParcelableArrayExtra(Intents.Recognize.RESULTS);
  163. if (results == null) {
  164. Log.e(TAG, "handleCompleted received null results");
  165. } else if (results.length <= 0) {
  166. Log.e(TAG, "handleCompleted received empty results");
  167. } else {
  168. EditText textresult = (EditText) findViewById(R.id.textresult);
  169. textresult.setText("");
  170. for (int i = 0; i < results.length; i++) {
  171. String result = postProcess(((Result) results[i]).getString());
  172. if (result.length() > 0) {
  173. textresult.append(result.trim() + "\n");
  174. }
  175. }
  176. }
  177. SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
  178. boolean clipboard = prefs.getBoolean(PrefsActivity.CLIPBOARD, PrefsActivity.DEFAULT_CLIPBOARD);
  179. if (clipboard) {
  180. copyToClipboard();
  181. }
  182. }
  183. /**
  184. * Removes words that consist of more than 1/3 non-word characters.
  185. *
  186. * @param text the text to process
  187. * @return the processed text
  188. */
  189. private String postProcess(String text) {
  190. String[] input = text.split(" ");
  191. String output = "";
  192. for (int i = 0; i < input.length; i++) {
  193. if (input[i].length() <= 0) {
  194. continue;
  195. }
  196. int letterCount = 0;
  197. for (int j = 0; j < input[i].length(); j++) {
  198. char chr = input[i].charAt(j);
  199. if (chr == '\n' || Character.isLetterOrDigit(chr)) {
  200. letterCount++;
  201. }
  202. }
  203. if (10 * letterCount / input[i].length() > 6) {
  204. output += input[i] + " ";
  205. }
  206. }
  207. return output;
  208. }
  209. @Override
  210. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  211. switch (requestCode) {
  212. case REQUEST_CAPTURE: {
  213. if (resultCode == RESULT_OK) {
  214. requestRecognize(data);
  215. } else {
  216. Toast.makeText(this, R.string.capture_failed, 5).show();
  217. Log.e(TAG, "REQUEST_CAPTURE received unexpected resultCode (" + resultCode + ")");
  218. }
  219. break;
  220. }
  221. case REQUEST_RECOGNIZE: {
  222. if (resultCode == RESULT_OK) {
  223. handleCompleted(data);
  224. } else if (resultCode == RESULT_CANCELED) {
  225. Toast.makeText(this, R.string.recognize_canceled, 3).show();
  226. Log.i(TAG, "REQUEST_RECOGNIZED received RESULT_CANCELED");
  227. } else {
  228. Toast.makeText(this, R.string.recognize_failed, 5).show();
  229. Log.e(TAG, "REQUEST_RECOGNIZE received unexpected resultCode (" + resultCode + ")");
  230. }
  231. break;
  232. }
  233. default: {
  234. Log.i(TAG, "Received unknown activity request code (" + requestCode + ")");
  235. super.onActivityResult(requestCode, resultCode, data);
  236. }
  237. }
  238. }
  239. @Override
  240. public void onClick(View v) {
  241. copyToClipboard();
  242. }
  243. private void copyToClipboard() {
  244. EditText textresult = (EditText) findViewById(R.id.textresult);
  245. Editable text = textresult.getText();
  246. ClipboardManager manager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
  247. manager.setText(text.toString());
  248. Toast.makeText(this, R.string.clipboard, 3).show();
  249. }
  250. }