OCR Configurable  1.0
 Todo Clases Namespaces Archivos Funciones Variables
CaptureActivityForOcr.java
Ir a la documentación de este archivo.
00001 /*
00002  * Copyright (C) 2008 ZXing authors
00003  * Copyright 2011 Robert Theis
00004  * Copyright 2012 Jaime Navarro Santapau
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *      http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00053 package edu.uoc.ocr;
00054 
00055 import com.googlecode.tesseract.android.TessBaseAPI;
00056 
00057 import edu.uoc.ocr.R;
00058 import edu.uoc.ocr.BeepManager;
00059 import edu.uoc.ocr.HelpActivity;
00060 import edu.uoc.ocr.OcrResult;
00061 import edu.uoc.ocr.PreferencesActivity;
00062 import edu.uoc.ocr.camera.CameraManager;
00063 import edu.uoc.ocr.camera.ShutterButton;
00064 import edu.uoc.ocr.LanguageCodeHelper;
00065 
00066 import android.app.Activity;
00067 import android.app.AlertDialog;
00068 import android.app.ProgressDialog;
00069 import android.content.Context;
00070 import android.content.Intent;
00071 import android.content.SharedPreferences;
00072 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
00073 import android.content.pm.PackageInfo;
00074 import android.content.pm.PackageManager;
00075 import android.graphics.Bitmap;
00076 import android.graphics.BitmapFactory;
00077 import android.graphics.Rect;
00078 import android.os.Bundle;
00079 import android.os.Environment;
00080 import android.os.Handler;
00081 import android.preference.PreferenceManager;
00082 import android.text.ClipboardManager;
00083 
00084 import android.util.Log;
00085 import android.util.TypedValue;
00086 import android.view.ContextMenu;
00087 import android.view.Gravity;
00088 import android.view.KeyEvent;
00089 import android.view.Menu;
00090 import android.view.MenuItem;
00091 import android.view.MotionEvent;
00092 import android.view.SurfaceHolder;
00093 import android.view.SurfaceView;
00094 import android.view.View;
00095 import android.view.Window;
00096 import android.view.WindowManager;
00097 import android.view.ContextMenu.ContextMenuInfo;
00098 import android.widget.ImageView;
00099 import android.widget.TextView;
00100 import android.widget.Toast;
00101 
00102 import java.io.File;
00103 import java.io.IOException;
00104 import java.util.Locale;
00105 
00113 public final class CaptureActivityForOcr extends Activity implements
00114                 SurfaceHolder.Callback, ShutterButton.OnShutterButtonListener {
00115 
00116         private static final String TAG = CaptureActivityForOcr.class.getSimpleName();
00117 
00118         // Note: These constants will be overridden by any default values defined in
00119         // preferences.xml.
00120 
00125         public static String DEFAULT_SOURCE_LANGUAGE_CODE;
00126         
00127         static {
00128                 Locale locale = Locale.getDefault();
00129 
00130                 if (locale.getLanguage().contentEquals("es"))
00131                         DEFAULT_SOURCE_LANGUAGE_CODE = "spa";
00132                 else if (locale.getLanguage().contentEquals("en"))
00133                         DEFAULT_SOURCE_LANGUAGE_CODE = "eng";
00134                 else if (locale.getLanguage().contentEquals("ca"))
00135                         DEFAULT_SOURCE_LANGUAGE_CODE = "cat";
00136                 else
00137                         DEFAULT_SOURCE_LANGUAGE_CODE = "spa";
00138         }
00139         
00140         
00141           
00143         public static final int OEM_TESSERACT_ONLY = 0;
00144 
00146         public static final String DEFAULT_PAGE_SEGMENTATION_MODE = "Auto";
00147 
00149         public static final boolean DEFAULT_TOGGLE_AUTO_FOCUS = false;
00150 
00155         public static final boolean DEFAULT_TOGGLE_BEEP = true;
00156 
00158         public static final boolean DEFAULT_TOGGLE_LIGHT = false;
00159 
00164         private static final boolean DISPLAY_SHUTTER_BUTTON = true;
00165 
00167         static final String DOWNLOAD_BASE = "http://tesseract-ocr.googlecode.com/files/";
00168 
00173         static final String OSD_FILENAME = "tesseract-ocr-3.01.osd.tar";
00174 
00179         static final String OSD_FILENAME_BASE = "osd.traineddata";
00180 
00182         static final String MANUAL_FILENAME_BASE = "man.traineddata";
00183 
00188         static final int MINIMUM_MEAN_CONFIDENCE = 0; // 0 means don't reject any
00189                                                                                                         // scored results
00190 
00191         // Context menu
00192         private static final int SETTINGS_ID = Menu.FIRST;
00193         private static final int ABOUT_ID = Menu.FIRST + 1;
00194 
00195         // Options menu, for copy to clipboard
00196         private static final int OPTIONS_COPY_RECOGNIZED_TEXT_ID = Menu.FIRST;
00197         private static final int OPTIONS_COPY_TRANSLATED_TEXT_ID = Menu.FIRST + 1;
00198         private static final int OPTIONS_SHARE_RECOGNIZED_TEXT_ID = Menu.FIRST + 2;
00199         private static final int OPTIONS_SHARE_TRANSLATED_TEXT_ID = Menu.FIRST + 3;
00200 
00201         private CameraManager cameraManager;
00202         private CaptureActivityHandler handler;
00203         private ViewfinderView viewfinderView;
00204         private SurfaceView surfaceView;
00205         private SurfaceHolder surfaceHolder;
00206         private TextView statusViewBottom;
00207         private TextView statusViewTop;
00208         private TextView ocrResultView;
00209         private TextView translationView;
00210         private View cameraButtonView;
00211         private View resultView;
00212         private View progressView;
00213         private OcrResult lastResult;
00214         private Bitmap lastBitmap;
00215         private boolean hasSurface;
00216         private BeepManager beepManager;
00217         private TessBaseAPI baseApi; // Java interface for the Tesseract OCR engine
00218         private String sourceLanguageCodeOcr; // ISO 639-3 language code
00219         private String sourceLanguageReadable; // Language name, for example,
00220                                                                                         // "English"
00221         private int pageSegmentationMode = TessBaseAPI.PageSegMode.PSM_AUTO;
00222         private int ocrEngineMode = OEM_TESSERACT_ONLY;
00223         private String characterBlacklist;
00224         private String characterWhitelist;
00225         private ShutterButton shutterButton;
00226         private SharedPreferences prefs;
00227         private OnSharedPreferenceChangeListener listener;
00228         private ProgressDialog dialog; // for initOcr - language download & unzip
00229         private ProgressDialog indeterminateDialog; // also for initOcr - init OCR
00230                                                                                                 // engine
00231         private boolean isEngineReady;
00232         private static boolean isFirstLaunch; // True if this is the first time the
00233                                                                                         // app is being run
00234 
00235         Handler getHandler() {
00236                 return handler;
00237         }
00238 
00239         TessBaseAPI getBaseApi() {
00240                 return baseApi;
00241         }
00242 
00243         CameraManager getCameraManager() {
00244                 return cameraManager;
00245         }
00246 
00247         @Override
00248         public void onCreate(Bundle icicle) {
00249                 super.onCreate(icicle);
00250 
00251                 checkFirstLaunch();
00252 
00253                 if (isFirstLaunch) {
00254                         setDefaultPreferences();
00255                 }
00256 
00257                 Window window = getWindow();
00258                 window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
00259                 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
00260                 setContentView(R.layout.capture);
00261                 viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
00262                 cameraButtonView = findViewById(R.id.camera_button_view);
00263                 resultView = findViewById(R.id.result_view);
00264 
00265                 statusViewBottom = (TextView) findViewById(R.id.status_view_bottom);
00266                 registerForContextMenu(statusViewBottom);
00267                 statusViewTop = (TextView) findViewById(R.id.status_view_top);
00268                 registerForContextMenu(statusViewTop);
00269 
00270                 handler = null;
00271                 lastResult = null;
00272                 hasSurface = false;
00273                 beepManager = new BeepManager(this);
00274 
00275                 // Camera shutter button
00276                 if (DISPLAY_SHUTTER_BUTTON) {
00277                         shutterButton = (ShutterButton) findViewById(R.id.shutter_button);
00278                         shutterButton.setOnShutterButtonListener(this);
00279                 }
00280 
00281                 ocrResultView = (TextView) findViewById(R.id.ocr_result_text_view);
00282                 registerForContextMenu(ocrResultView);
00283                 translationView = (TextView) findViewById(R.id.translation_text_view);
00284                 registerForContextMenu(translationView);
00285 
00286                 progressView = (View) findViewById(R.id.indeterminate_progress_indicator_view);
00287 
00288                 cameraManager = new CameraManager(getApplication());
00289                 viewfinderView.setCameraManager(cameraManager);
00290 
00291                 // Set listener to change the size of the viewfinder rectangle.
00292                 viewfinderView.setOnTouchListener(new View.OnTouchListener() {
00293                         int lastX = -1;
00294                         int lastY = -1;
00295 
00296                         @Override
00297                         public boolean onTouch(View v, MotionEvent event) {
00298                                 switch (event.getAction()) {
00299                                 case MotionEvent.ACTION_DOWN:
00300                                         lastX = -1;
00301                                         lastY = -1;
00302                                         return true;
00303                                 case MotionEvent.ACTION_MOVE:
00304                                         int currentX = (int) event.getX();
00305                                         int currentY = (int) event.getY();
00306 
00307                                         try {
00308                                                 Rect rect = cameraManager.getFramingRect();
00309 
00310                                                 final int BUFFER = 50;
00311                                                 final int BIG_BUFFER = 60;
00312                                                 if (lastX >= 0) {
00313                                                         // Adjust the size of the viewfinder rectangle.
00314                                                         // Check if the touch event occurs in the corner
00315                                                         // areas first, because the regions overlap.
00316                                                         if (((currentX >= rect.left - BIG_BUFFER && currentX <= rect.left
00317                                                                         + BIG_BUFFER) || (lastX >= rect.left
00318                                                                         - BIG_BUFFER && lastX <= rect.left
00319                                                                         + BIG_BUFFER))
00320                                                                         && ((currentY <= rect.top + BIG_BUFFER && currentY >= rect.top
00321                                                                                         - BIG_BUFFER) || (lastY <= rect.top
00322                                                                                         + BIG_BUFFER && lastY >= rect.top
00323                                                                                         - BIG_BUFFER))) {
00324                                                                 // Top left corner: adjust both top and left
00325                                                                 // sides
00326                                                                 cameraManager.adjustFramingRect(
00327                                                                                 2 * (lastX - currentX),
00328                                                                                 2 * (lastY - currentY));
00329                                                                 viewfinderView.removeResultText();
00330                                                         } else if (((currentX >= rect.right - BIG_BUFFER && currentX <= rect.right
00331                                                                         + BIG_BUFFER) || (lastX >= rect.right
00332                                                                         - BIG_BUFFER && lastX <= rect.right
00333                                                                         + BIG_BUFFER))
00334                                                                         && ((currentY <= rect.top + BIG_BUFFER && currentY >= rect.top
00335                                                                                         - BIG_BUFFER) || (lastY <= rect.top
00336                                                                                         + BIG_BUFFER && lastY >= rect.top
00337                                                                                         - BIG_BUFFER))) {
00338                                                                 // Top right corner: adjust both top and right
00339                                                                 // sides
00340                                                                 cameraManager.adjustFramingRect(
00341                                                                                 2 * (currentX - lastX),
00342                                                                                 2 * (lastY - currentY));
00343                                                                 viewfinderView.removeResultText();
00344                                                         } else if (((currentX >= rect.left - BIG_BUFFER && currentX <= rect.left
00345                                                                         + BIG_BUFFER) || (lastX >= rect.left
00346                                                                         - BIG_BUFFER && lastX <= rect.left
00347                                                                         + BIG_BUFFER))
00348                                                                         && ((currentY <= rect.bottom + BIG_BUFFER && currentY >= rect.bottom
00349                                                                                         - BIG_BUFFER) || (lastY <= rect.bottom
00350                                                                                         + BIG_BUFFER && lastY >= rect.bottom
00351                                                                                         - BIG_BUFFER))) {
00352                                                                 // Bottom left corner: adjust both bottom and
00353                                                                 // left sides
00354                                                                 cameraManager.adjustFramingRect(
00355                                                                                 2 * (lastX - currentX),
00356                                                                                 2 * (currentY - lastY));
00357                                                                 viewfinderView.removeResultText();
00358                                                         } else if (((currentX >= rect.right - BIG_BUFFER && currentX <= rect.right
00359                                                                         + BIG_BUFFER) || (lastX >= rect.right
00360                                                                         - BIG_BUFFER && lastX <= rect.right
00361                                                                         + BIG_BUFFER))
00362                                                                         && ((currentY <= rect.bottom + BIG_BUFFER && currentY >= rect.bottom
00363                                                                                         - BIG_BUFFER) || (lastY <= rect.bottom
00364                                                                                         + BIG_BUFFER && lastY >= rect.bottom
00365                                                                                         - BIG_BUFFER))) {
00366                                                                 // Bottom right corner: adjust both bottom and
00367                                                                 // right sides
00368                                                                 cameraManager.adjustFramingRect(
00369                                                                                 2 * (currentX - lastX),
00370                                                                                 2 * (currentY - lastY));
00371                                                                 viewfinderView.removeResultText();
00372                                                         } else if (((currentX >= rect.left - BUFFER && currentX <= rect.left
00373                                                                         + BUFFER) || (lastX >= rect.left - BUFFER && lastX <= rect.left
00374                                                                         + BUFFER))
00375                                                                         && ((currentY <= rect.bottom && currentY >= rect.top) || (lastY <= rect.bottom && lastY >= rect.top))) {
00376                                                                 // Adjusting left side: event falls within
00377                                                                 // BUFFER pixels of left side, and between top
00378                                                                 // and bottom side limits
00379                                                                 cameraManager.adjustFramingRect(
00380                                                                                 2 * (lastX - currentX), 0);
00381                                                                 viewfinderView.removeResultText();
00382                                                         } else if (((currentX >= rect.right - BUFFER && currentX <= rect.right
00383                                                                         + BUFFER) || (lastX >= rect.right - BUFFER && lastX <= rect.right
00384                                                                         + BUFFER))
00385                                                                         && ((currentY <= rect.bottom && currentY >= rect.top) || (lastY <= rect.bottom && lastY >= rect.top))) {
00386                                                                 // Adjusting right side: event falls within
00387                                                                 // BUFFER pixels of right side, and between top
00388                                                                 // and bottom side limits
00389                                                                 cameraManager.adjustFramingRect(
00390                                                                                 2 * (currentX - lastX), 0);
00391                                                                 viewfinderView.removeResultText();
00392                                                         } else if (((currentY <= rect.top + BUFFER && currentY >= rect.top
00393                                                                         - BUFFER) || (lastY <= rect.top + BUFFER && lastY >= rect.top
00394                                                                         - BUFFER))
00395                                                                         && ((currentX <= rect.right && currentX >= rect.left) || (lastX <= rect.right && lastX >= rect.left))) {
00396                                                                 // Adjusting top side: event falls within BUFFER
00397                                                                 // pixels of top side, and between left and
00398                                                                 // right side limits
00399                                                                 cameraManager.adjustFramingRect(0,
00400                                                                                 2 * (lastY - currentY));
00401                                                                 viewfinderView.removeResultText();
00402                                                         } else if (((currentY <= rect.bottom + BUFFER && currentY >= rect.bottom
00403                                                                         - BUFFER) || (lastY <= rect.bottom + BUFFER && lastY >= rect.bottom
00404                                                                         - BUFFER))
00405                                                                         && ((currentX <= rect.right && currentX >= rect.left) || (lastX <= rect.right && lastX >= rect.left))) {
00406                                                                 // Adjusting bottom side: event falls within
00407                                                                 // BUFFER pixels of bottom side, and between
00408                                                                 // left and right side limits
00409                                                                 cameraManager.adjustFramingRect(0,
00410                                                                                 2 * (currentY - lastY));
00411                                                                 viewfinderView.removeResultText();
00412                                                         }
00413                                                 }
00414                                         } catch (NullPointerException e) {
00415                                                 Log.e(TAG, "Framing rect not available", e);
00416                                         }
00417                                         v.invalidate();
00418                                         lastX = currentX;
00419                                         lastY = currentY;
00420                                         return true;
00421                                 case MotionEvent.ACTION_UP:
00422                                         lastX = -1;
00423                                         lastY = -1;
00424                                         return true;
00425                                 }
00426                                 return false;
00427                         }
00428                 });
00429 
00430                 isEngineReady = false;
00431         }
00432 
00433         @Override
00434         protected void onResume() {
00435                 super.onResume();
00436                 resetStatusView();
00437 
00438                 String previousSourceLanguageCodeOcr = sourceLanguageCodeOcr;
00439                 int previousOcrEngineMode = ocrEngineMode;
00440 
00441                 retrievePreferences();
00442 
00443                 // Set up the camera preview surface.
00444                 surfaceView = (SurfaceView) findViewById(R.id.preview_view);
00445                 surfaceHolder = surfaceView.getHolder();
00446                 if (!hasSurface) {
00447                         surfaceHolder.addCallback(this);
00448                         surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
00449                 }
00450 
00451                 // Comment out the following block to test non-OCR functions without an
00452                 // SD card
00453 
00454                 // Do OCR engine initialization, if necessary
00455                 boolean doNewInit = (baseApi == null)
00456                                 || !sourceLanguageCodeOcr.equals(previousSourceLanguageCodeOcr)
00457                                 || ocrEngineMode != previousOcrEngineMode;
00458                 if (doNewInit) {
00459                         // Initialize the OCR engine
00460                         File storageDirectory = getStorageDirectory();
00461                         if (storageDirectory != null) {
00462                                 initOcrEngine(storageDirectory, sourceLanguageCodeOcr,
00463                                                 sourceLanguageReadable);
00464                         }
00465                 } else {
00466                         // We already have the engine initialized, so just start the camera.
00467                         resumeOCR();
00468                 }
00469         }
00470 
00479         void resumeOCR() {
00480                 Log.d(TAG, "resumeOCR()");
00481 
00482                 // This method is called when Tesseract has already been successfully
00483                 // initialized, so set
00484                 // isEngineReady = true here.
00485                 isEngineReady = true;
00486 
00487                 if (baseApi != null) {
00488                         baseApi.setPageSegMode(pageSegmentationMode);
00489                         baseApi.setVariable(TessBaseAPI.VAR_CHAR_BLACKLIST,
00490                                         characterBlacklist);
00491                         baseApi.setVariable(TessBaseAPI.VAR_CHAR_WHITELIST,
00492                                         characterWhitelist);
00493                 }
00494 
00495                 if (hasSurface) {
00496                         // The activity was paused but not stopped, so the surface still
00497                         // exists. Therefore
00498                         // surfaceCreated() won't be called, so init the camera here.
00499                         initCamera(surfaceHolder);
00500                 }
00501         }
00502 
00503         @Override
00504         public void surfaceCreated(SurfaceHolder holder) {
00505                 Log.d(TAG, "surfaceCreated()");
00506 
00507                 if (holder == null) {
00508                         Log.e(TAG, "surfaceCreated gave us a null surface");
00509                 }
00510 
00511                 // Only initialize the camera if the OCR engine is ready to go.
00512                 if (!hasSurface && isEngineReady) {
00513                         Log.d(TAG, "surfaceCreated(): calling initCamera()...");
00514                         initCamera(holder);
00515                 }
00516                 hasSurface = true;
00517         }
00518 
00523         private void initCamera(SurfaceHolder surfaceHolder) {
00524                 Log.d(TAG, "initCamera()");
00525                 if (surfaceHolder == null) {
00526                         throw new IllegalStateException("No SurfaceHolder provided");
00527                 }
00528                 try {
00529 
00530                         // Open and initialize the camera
00531                         cameraManager.openDriver(surfaceHolder);
00532 
00533                         // Creating the handler starts the preview, which can also throw a
00534                         // RuntimeException.
00535                         handler = new CaptureActivityHandler(this, cameraManager);
00536 
00537                 } catch (IOException ioe) {
00538                         showErrorMessage("Error",
00539                                         "Could not initialize camera. Please try restarting device.");
00540                 } catch (RuntimeException e) {
00541                         // Barcode Scanner has seen crashes in the wild of this variety:
00542                         // java.?lang.?RuntimeException: Fail to connect to camera service
00543                         showErrorMessage("Error",
00544                                         "Could not initialize camera. Please try restarting device.");
00545                 }
00546         }
00547 
00548         @Override
00549         protected void onPause() {
00550                 if (handler != null) {
00551                         handler.quitSynchronously();
00552                 }
00553 
00554                 // Stop using the camera, to avoid conflicting with other camera-based
00555                 // apps
00556                 cameraManager.closeDriver();
00557 
00558                 if (!hasSurface) {
00559                         SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
00560                         SurfaceHolder surfaceHolder = surfaceView.getHolder();
00561                         surfaceHolder.removeCallback(this);
00562                 }
00563                 super.onPause();
00564         }
00565 
00566         void stopHandler() {
00567                 if (handler != null) {
00568                         handler.stop();
00569                 }
00570         }
00571 
00572         @Override
00573         protected void onDestroy() {
00574                 if (baseApi != null) {
00575                         baseApi.end();
00576                 }
00577                 super.onDestroy();
00578         }
00579 
00580         @Override
00581         public boolean onKeyDown(int keyCode, KeyEvent event) {
00582                 if (keyCode == KeyEvent.KEYCODE_BACK) {
00583 
00584                         // Exit the app if we're not viewing an OCR result.
00585                         if (lastResult == null) {
00586                                 setResult(RESULT_CANCELED);
00587                                 finish();
00588                                 return true;
00589                         } else {
00590                                 // Go back to previewing in regular OCR mode.
00591                                 resetStatusView();
00592                                 if (handler != null) {
00593                                         handler.sendEmptyMessage(R.id.restart_preview);
00594                                 }
00595                                 return true;
00596                         }
00597                 } else if (keyCode == KeyEvent.KEYCODE_CAMERA) {
00598 
00599                         handler.hardwareShutterButtonClick();
00600                         return true;
00601 
00602                 } else if (keyCode == KeyEvent.KEYCODE_FOCUS) {
00603                         // Only perform autofocus if user is not holding down the button.
00604                         if (event.getRepeatCount() == 0) {
00605                                 cameraManager.requestAutoFocus(500L);
00606                         }
00607                         return true;
00608                 }
00609                 return super.onKeyDown(keyCode, event);
00610         }
00611 
00612         @Override
00613         public boolean onCreateOptionsMenu(Menu menu) {
00614                 super.onCreateOptionsMenu(menu);
00615                 menu.add(0, SETTINGS_ID, 0, getString(R.string.menu_conf)).setIcon(
00616                                 android.R.drawable.ic_menu_preferences);
00617                 menu.add(0, ABOUT_ID, 0,  getString(R.string.menu_about)).setIcon(
00618                                 android.R.drawable.ic_menu_info_details);
00619                 return true;
00620         }
00621 
00622         @Override
00623         public boolean onOptionsItemSelected(MenuItem item) {
00624                 Intent intent;
00625                 switch (item.getItemId()) {
00626                 case SETTINGS_ID: {
00627                         intent = new Intent().setClass(this, PreferencesActivity.class);
00628                         startActivity(intent);
00629                         break;
00630                 }
00631                 case ABOUT_ID: {
00632                         intent = new Intent(this, HelpActivity.class);
00633                         intent.putExtra(HelpActivity.REQUESTED_PAGE_KEY,
00634                                         HelpActivity.ABOUT_PAGE);
00635                         startActivity(intent);
00636                         break;
00637                 }
00638                 }
00639                 return super.onOptionsItemSelected(item);
00640         }
00641 
00642         public void surfaceDestroyed(SurfaceHolder holder) {
00643                 hasSurface = false;
00644         }
00645 
00646         public void surfaceChanged(SurfaceHolder holder, int format, int width,
00647                         int height) {
00648         }
00649 
00656         private boolean setSourceLanguage(String languageCode) {
00657                 sourceLanguageCodeOcr = languageCode;
00658                 sourceLanguageReadable = LanguageCodeHelper.getOcrLanguageName(this,
00659                                 languageCode);
00660                 return true;
00661         }
00662 
00668         private File getStorageDirectory() {
00669                 // Log.d(TAG, "getStorageDirectory(): API level is " +
00670                 // Integer.valueOf(android.os.Build.VERSION.SDK_INT));
00671 
00672                 String state = null;
00673                 try {
00674                         state = Environment.getExternalStorageState();
00675                 } catch (RuntimeException e) {
00676                         Log.e(TAG, "Is the SD card visible?", e);
00677                         showErrorMessage("Error",
00678                                         "Required external storage (such as an SD card) is unavailable.");
00679                 }
00680 
00681                 if (Environment.MEDIA_MOUNTED.equals(Environment
00682                                 .getExternalStorageState())) {
00683 
00684                         try {
00685                                 return getExternalFilesDir(Environment.MEDIA_MOUNTED);
00686                         } catch (NullPointerException e) {
00687                                 // We get an error here if the SD card is visible, but full
00688                                 Log.e(TAG, "External storage is unavailable");
00689                                 showErrorMessage("Error",
00690                                                 "Required external storage (such as an SD card) is full or unavailable.");
00691                         }
00692 
00693                 } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
00694                         // We can only read the media
00695                         Log.e(TAG, "External storage is read-only");
00696                         showErrorMessage(
00697                                         "Error",
00698                                         "Required external storage (such as an SD card) is unavailable for data storage.");
00699                 } else {
00700                         // Something else is wrong. It may be one of many other states, but
00701                         // all we need
00702                         // to know is we can neither read nor write
00703                         Log.e(TAG, "External storage is unavailable");
00704                         showErrorMessage("Error",
00705                                         "Required external storage (such as an SD card) is unavailable or corrupted.");
00706                 }
00707                 return null;
00708         }
00709 
00718         private void initOcrEngine(File storageRoot, String languageCode,
00719                         String languageName) {
00720                 isEngineReady = false;
00721 
00722                 // Set up the dialog box for the thermometer-style download progress
00723                 // indicator
00724                 if (dialog != null) {
00725                         dialog.dismiss();
00726                 }
00727                 dialog = new ProgressDialog(this);
00728 
00729                 // Display the name of the OCR engine we're initializing in the
00730                 // indeterminate progress dialog box
00731                 indeterminateDialog = new ProgressDialog(this);
00732                 indeterminateDialog.setTitle(getString(R.string.dialogo_1));
00733                 indeterminateDialog.setCancelable(false);
00734                 indeterminateDialog.show();
00735 
00736                 if (handler != null) {
00737                         handler.quitSynchronously();
00738                 }
00739 
00740                 // Start AsyncTask to install language data and init OCR
00741                 baseApi = new TessBaseAPI();
00742                 new OcrInitAsyncTask(this, baseApi, dialog, indeterminateDialog,
00743                                 languageCode, languageName)
00744                                 .execute(storageRoot.toString());
00745         }
00746 
00753         boolean handleOcrDecode(OcrResult ocrResult) {
00754                 lastResult = ocrResult;
00755 
00756                 // Test whether the result is null
00757                 if (ocrResult.getText() == null || ocrResult.getText().equals("")) {
00758                         Toast toast = Toast.makeText(this, getString(R.string.dialogo_2),
00759                                         Toast.LENGTH_SHORT);
00760                         toast.setGravity(Gravity.TOP, 0, 0);
00761                         toast.show();
00762                         return false;
00763                 }
00764 
00765                 // Turn off capture-related UI elements
00766                 shutterButton.setVisibility(View.GONE);
00767                 statusViewBottom.setVisibility(View.GONE);
00768                 statusViewTop.setVisibility(View.GONE);
00769                 cameraButtonView.setVisibility(View.GONE);
00770                 viewfinderView.setVisibility(View.GONE);
00771                 resultView.setVisibility(View.VISIBLE);
00772 
00773                 ImageView bitmapImageView = (ImageView) findViewById(R.id.image_view);
00774                 lastBitmap = ocrResult.getBitmap();
00775                 if (lastBitmap == null) {
00776                         bitmapImageView.setImageBitmap(BitmapFactory.decodeResource(
00777                                         getResources(), R.drawable.ic_launcher));
00778                 } else {
00779                         bitmapImageView.setImageBitmap(lastBitmap);
00780                 }
00781 
00782                 // Display the recognized text
00783                 TextView sourceLanguageTextView = (TextView) findViewById(R.id.source_language_text_view);
00784                 sourceLanguageTextView.setText(sourceLanguageReadable);
00785                 TextView ocrResultTextView = (TextView) findViewById(R.id.ocr_result_text_view);
00786                 ocrResultTextView.setText(ocrResult.getText());
00787 
00788                 // Crudely scale betweeen 22 and 32 -- bigger font for shorter text
00789                 int scaledSize = Math.max(22, 32 - ocrResult.getText().length() / 4);
00790                 ocrResultTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, scaledSize);
00791 
00792                 TextView translationLanguageLabelTextView = (TextView) findViewById(R.id.translation_language_label_text_view);
00793                 TextView translationLanguageTextView = (TextView) findViewById(R.id.translation_language_text_view);
00794                 TextView translationTextView = (TextView) findViewById(R.id.translation_text_view);
00795 
00796                 translationLanguageLabelTextView.setVisibility(View.GONE);
00797                 translationLanguageTextView.setVisibility(View.GONE);
00798                 translationTextView.setVisibility(View.GONE);
00799                 progressView.setVisibility(View.GONE);
00800                 setProgressBarVisibility(false);
00801 
00802                 return true;
00803         }
00804 
00805         @Override
00806         public void onCreateContextMenu(ContextMenu menu, View v,
00807                         ContextMenuInfo menuInfo) {
00808                 super.onCreateContextMenu(menu, v, menuInfo);
00809                 if (v.equals(ocrResultView)) {
00810                         menu.add(Menu.NONE, OPTIONS_COPY_RECOGNIZED_TEXT_ID, Menu.NONE,
00811                                         getString(R.string.dialogo_5));
00812                         menu.add(Menu.NONE, OPTIONS_SHARE_RECOGNIZED_TEXT_ID, Menu.NONE,
00813                                         getString(R.string.dialogo_6));
00814                 } else if (v.equals(translationView)) {
00815                         menu.add(Menu.NONE, OPTIONS_COPY_TRANSLATED_TEXT_ID, Menu.NONE,
00816                                         getString(R.string.dialogo_5));
00817                         menu.add(Menu.NONE, OPTIONS_SHARE_TRANSLATED_TEXT_ID, Menu.NONE,
00818                                         getString(R.string.dialogo_6));
00819                 }
00820         }
00821 
00822           @Override
00823           public boolean onContextItemSelected(MenuItem item) {
00824             ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
00825             switch (item.getItemId()) {
00826 
00827             case OPTIONS_COPY_RECOGNIZED_TEXT_ID:
00828                 clipboardManager.setText(ocrResultView.getText());
00829               if (clipboardManager.hasText()) {
00830                 Toast toast = Toast.makeText(this, getString(R.string.dialogo_14), Toast.LENGTH_LONG);
00831                 toast.setGravity(Gravity.BOTTOM, 0, 0);
00832                 toast.show();
00833               }
00834               return true;
00835             case OPTIONS_SHARE_RECOGNIZED_TEXT_ID:
00836                 Intent shareRecognizedTextIntent = new Intent(android.content.Intent.ACTION_SEND);
00837                 shareRecognizedTextIntent.setType("text/plain");
00838                 shareRecognizedTextIntent.putExtra(android.content.Intent.EXTRA_TEXT, ocrResultView.getText());
00839                 startActivity(Intent.createChooser(shareRecognizedTextIntent,  getString(R.string.dialogo_15)));
00840                 return true;
00841             case OPTIONS_COPY_TRANSLATED_TEXT_ID:
00842                 clipboardManager.setText(translationView.getText());
00843               if (clipboardManager.hasText()) {
00844                 Toast toast = Toast.makeText(this, getString(R.string.dialogo_14), Toast.LENGTH_LONG);
00845                 toast.setGravity(Gravity.BOTTOM, 0, 0);
00846                 toast.show();
00847               }
00848               return true;
00849             case OPTIONS_SHARE_TRANSLATED_TEXT_ID:
00850                 Intent shareTranslatedTextIntent = new Intent(android.content.Intent.ACTION_SEND);
00851                 shareTranslatedTextIntent.setType("text/plain");
00852                 shareTranslatedTextIntent.putExtra(android.content.Intent.EXTRA_TEXT, translationView.getText());
00853                 startActivity(Intent.createChooser(shareTranslatedTextIntent,  getString(R.string.dialogo_15)));
00854                 return true;
00855             default:
00856               return super.onContextItemSelected(item);
00857             }
00858           }
00859         
00863         private void resetStatusView() {
00864                 resultView.setVisibility(View.GONE);
00865 
00866                 viewfinderView.setVisibility(View.VISIBLE);
00867                 cameraButtonView.setVisibility(View.VISIBLE);
00868                 if (DISPLAY_SHUTTER_BUTTON) {
00869                         shutterButton.setVisibility(View.VISIBLE);
00870                 }
00871                 lastResult = null;
00872                 viewfinderView.removeResultText();
00873         }
00874 
00879         void showLanguageName() {
00880                 Toast toast = Toast.makeText(this, "OCR: " + sourceLanguageReadable,
00881                                 Toast.LENGTH_LONG);
00882                 toast.setGravity(Gravity.TOP, 0, 0);
00883                 toast.show();
00884         }
00885 
00886         void setButtonVisibility(boolean visible) {
00887                 if (shutterButton != null && visible == true && DISPLAY_SHUTTER_BUTTON) {
00888                         shutterButton.setVisibility(View.VISIBLE);
00889                 } else if (shutterButton != null) {
00890                         shutterButton.setVisibility(View.GONE);
00891                 }
00892         }
00893 
00899         void setShutterButtonClickable(boolean clickable) {
00900                 shutterButton.setClickable(clickable);
00901         }
00902 
00904         void drawViewfinder() {
00905                 viewfinderView.drawViewfinder();
00906         }
00907 
00908         @Override
00909         public void onShutterButtonClick(ShutterButton b) {
00910                 if (handler != null) {
00911                         handler.shutterButtonClick();
00912                 }
00913         }
00914 
00915         @Override
00916         public void onShutterButtonFocus(ShutterButton b, boolean pressed) {
00917                 requestDelayedAutoFocus();
00918         }
00919 
00925         private void requestDelayedAutoFocus() {
00926                 // Wait 350 ms before focusing to avoid interfering with quick button
00927                 // presses when
00928                 // the user just wants to take a picture without focusing.
00929                 cameraManager.requestAutoFocus(350L);
00930         }
00931 
00932         static boolean getFirstLaunch() {
00933                 return isFirstLaunch;
00934         }
00935 
00945         private boolean checkFirstLaunch() {
00946                 try {
00947                         PackageInfo info = getPackageManager().getPackageInfo(
00948                                         getPackageName(), 0);
00949                         int currentVersion = info.versionCode;
00950                         SharedPreferences prefs = PreferenceManager
00951                                         .getDefaultSharedPreferences(this);
00952                         int lastVersion = prefs.getInt(
00953                                         PreferencesActivity.KEY_HELP_VERSION_SHOWN, 0);
00954                         if (lastVersion == 0) {
00955                                 isFirstLaunch = true;
00956                         } else {
00957                                 isFirstLaunch = false;
00958                         }
00959                         if (currentVersion > lastVersion) {
00960 
00961                                 // Record the last version for which we last displayed the
00962                                 // What's New (Help) page
00963                                 prefs.edit()
00964                                                 .putInt(PreferencesActivity.KEY_HELP_VERSION_SHOWN,
00965                                                                 currentVersion).commit();
00966                                 Intent intent = new Intent(this, HelpActivity.class);
00967                                 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
00968 
00969                                 // Show the default page on a clean install, and the what's new
00970                                 // page on an upgrade.
00971                                 String page = lastVersion == 0 ? HelpActivity.DEFAULT_PAGE
00972                                                 : HelpActivity.WHATS_NEW_PAGE;
00973                                 intent.putExtra(HelpActivity.REQUESTED_PAGE_KEY, page);
00974                                 startActivity(intent);
00975                                 return true;
00976                         }
00977                 } catch (PackageManager.NameNotFoundException e) {
00978                         Log.w(TAG, e);
00979                 }
00980                 return false;
00981         }
00982 
00987         private void retrievePreferences() {
00988                 prefs = PreferenceManager.getDefaultSharedPreferences(this);
00989 
00990                 // Retrieve from preferences, and set in this Activity, the language
00991                 // preferences
00992                 PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
00993                 setSourceLanguage(prefs.getString(
00994                                 PreferencesActivity.KEY_SOURCE_LANGUAGE_PREFERENCE,
00995                                 CaptureActivityForOcr.DEFAULT_SOURCE_LANGUAGE_CODE));
00996 
00997                 // Retrieve from preferences, and set in this Activity, the page
00998                 // segmentation mode preference
00999                 String[] pageSegmentationModes = getResources().getStringArray(
01000                                 R.array.pagesegmentationmodes);
01001                 String pageSegmentationModeName = prefs.getString(
01002                                 PreferencesActivity.KEY_PAGE_SEGMENTATION_MODE,
01003                                 pageSegmentationModes[0]);
01004                 if (pageSegmentationModeName.equals(pageSegmentationModes[0])) {
01005                         pageSegmentationMode = TessBaseAPI.PageSegMode.PSM_AUTO_OSD;
01006                 } else if (pageSegmentationModeName.equals(pageSegmentationModes[1])) {
01007                         pageSegmentationMode = TessBaseAPI.PageSegMode.PSM_AUTO;
01008                 } else if (pageSegmentationModeName.equals(pageSegmentationModes[2])) {
01009                         pageSegmentationMode = TessBaseAPI.PageSegMode.PSM_SINGLE_BLOCK;
01010                 } else if (pageSegmentationModeName.equals(pageSegmentationModes[3])) {
01011                         pageSegmentationMode = TessBaseAPI.PageSegMode.PSM_SINGLE_CHAR;
01012                 } else if (pageSegmentationModeName.equals(pageSegmentationModes[4])) {
01013                         pageSegmentationMode = TessBaseAPI.PageSegMode.PSM_SINGLE_COLUMN;
01014                 } else if (pageSegmentationModeName.equals(pageSegmentationModes[5])) {
01015                         pageSegmentationMode = TessBaseAPI.PageSegMode.PSM_SINGLE_LINE;
01016                 } else if (pageSegmentationModeName.equals(pageSegmentationModes[6])) {
01017                         pageSegmentationMode = TessBaseAPI.PageSegMode.PSM_SINGLE_WORD;
01018                 } else if (pageSegmentationModeName.equals(pageSegmentationModes[7])) {
01019                         pageSegmentationMode = TessBaseAPI.PageSegMode.PSM_SINGLE_BLOCK_VERT_TEXT;
01020                 }
01021 
01022                 // Retrieve from preferences, and set in this Activity, the character
01023                 // blacklist and whitelist
01024                 characterBlacklist = OcrCharacterHelper.getBlacklist(prefs,
01025                                 sourceLanguageCodeOcr);
01026                 characterWhitelist = OcrCharacterHelper.getWhitelist(prefs,
01027                                 sourceLanguageCodeOcr);
01028 
01029                 prefs.registerOnSharedPreferenceChangeListener(listener);
01030 
01031                 beepManager.updatePrefs();
01032         }
01033 
01038         private void setDefaultPreferences() {
01039                 prefs = PreferenceManager.getDefaultSharedPreferences(this);
01040 
01041                 // Recognition language
01042                 prefs.edit()
01043                                 .putString(PreferencesActivity.KEY_SOURCE_LANGUAGE_PREFERENCE,
01044                                                 CaptureActivityForOcr.DEFAULT_SOURCE_LANGUAGE_CODE).commit();
01045 
01046                 // Autofocus
01047                 prefs.edit()
01048                                 .putBoolean(PreferencesActivity.KEY_AUTO_FOCUS,
01049                                                 CaptureActivityForOcr.DEFAULT_TOGGLE_AUTO_FOCUS).commit();
01050 
01051                 // Beep
01052                 prefs.edit()
01053                                 .putBoolean(PreferencesActivity.KEY_PLAY_BEEP,
01054                                                 CaptureActivityForOcr.DEFAULT_TOGGLE_BEEP).commit();
01055 
01056                 // Character blacklist
01057                 prefs.edit()
01058                                 .putString(
01059                                                 PreferencesActivity.KEY_CHARACTER_BLACKLIST,
01060                                                 OcrCharacterHelper
01061                                                                 .getDefaultBlacklist(CaptureActivityForOcr.DEFAULT_SOURCE_LANGUAGE_CODE))
01062                                 .commit();
01063 
01064                 // Character whitelist
01065                 prefs.edit()
01066                                 .putString(
01067                                                 PreferencesActivity.KEY_CHARACTER_WHITELIST,
01068                                                 OcrCharacterHelper
01069                                                                 .getDefaultWhitelist(CaptureActivityForOcr.DEFAULT_SOURCE_LANGUAGE_CODE))
01070                                 .commit();
01071 
01072                 // Page segmentation mode
01073                 prefs.edit()
01074                                 .putString(PreferencesActivity.KEY_PAGE_SEGMENTATION_MODE,
01075                                                 CaptureActivityForOcr.DEFAULT_PAGE_SEGMENTATION_MODE)
01076                                 .commit();
01077 
01078                 // Light
01079                 prefs.edit()
01080                                 .putBoolean(PreferencesActivity.KEY_TOGGLE_LIGHT,
01081                                                 CaptureActivityForOcr.DEFAULT_TOGGLE_LIGHT).commit();
01082         }
01083 
01084         void displayProgressDialog() {
01085                 // Set up the indeterminate progress dialog box
01086                 indeterminateDialog = new ProgressDialog(this);
01087                 indeterminateDialog.setTitle(getString(R.string.dialogo_1));
01088                 String ocrEngineModeName = "Tesseract";
01089 
01090                         indeterminateDialog.setMessage(getString(R.string.dialogo_4)
01091                                         + " " + ocrEngineModeName + "...");
01092                         
01093                 indeterminateDialog.setCancelable(false);
01094                 indeterminateDialog.show();
01095         }
01096 
01097         ProgressDialog getProgressDialog() {
01098                 return indeterminateDialog;
01099         }
01100 
01108         void showErrorMessage(String title, String message) {
01109                 new AlertDialog.Builder(this).setTitle(title).setMessage(message)
01110                                 .setOnCancelListener(new FinishListener(this))
01111                                 .setPositiveButton(getString(R.string.boton_done), new FinishListener(this)).show();
01112         }
01113 }
 Todo Clases Namespaces Archivos Funciones Variables