2012-10-13 47 views
4

我想在使用Tesseract的Android上构建一个OCR应用程序,但是当我保存图片时,应用程序会崩溃。正在使用Tesseract的OCR Android应用程序

我和教程Simple Android Photo Capture 与引导Making a Simple OCR Android App using Tesseract OCR功能打造的照片拍摄。

这是我使用的代码:

package com.mmm.pitter; 

import java.io.File; 
import java.io.IOException; 

import com.mmm.pitter.R; 
import com.googlecode.tesseract.android.*; 
import com.googlecode.leptonica.android.*; 

import android.app.Activity; 
import android.content.Intent; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Matrix; 
import android.media.ExifInterface; 
import android.net.Uri; 
import android.os.Bundle; 
import android.os.Environment; 
import android.provider.MediaStore; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.TextView; 

public class PitterActivity extends Activity 
{ 
    protected Button _button; 
    protected ImageView _image; 
    protected TextView _field; 
    protected String _path; 
    protected boolean _taken; 

    protected static final String PHOTO_TAKEN = "photo_taken"; 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.main); 

     _image = (ImageView) findViewById(R.id.image); 
     _field = (TextView) findViewById(R.id.field); 
     _button = (Button) findViewById(R.id.button); 
     _button.setOnClickListener(new ButtonClickHandler()); 

     _path = Environment.getExternalStorageDirectory() + "/images/make_machine_example.jpg"; 
    } 

    public class ButtonClickHandler implements View.OnClickListener 
    { 
     public void onClick(View view){ 
      Log.i("MakeMachine", "ButtonClickHandler.onClick()"); 
      startCameraActivity(); 
     } 
    } 

    protected void startCameraActivity() 
    { 
     Log.i("MakeMachine", "startCameraActivity()"); 
     File file = new File(_path); 
     Uri outputFileUri = Uri.fromFile(file); 

     Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
     intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); 

     startActivityForResult(intent, 0); 
    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    { 
     Log.i("MakeMachine", "resultCode: " + resultCode); 
     switch(resultCode) 
     { 
      case 0: 
       Log.i("MakeMachine", "User cancelled"); 
       break; 

      case -1: 
       try { 
        onPhotoTaken(); 
       } 
       catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       break; 
     } 
    } 

    protected void onPhotoTaken() throws IOException 
    { 
     Log.i("MakeMachine", "onPhotoTaken"); 

     _taken = true; 

     BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inSampleSize = 4; 

     Bitmap bitmap = BitmapFactory.decodeFile(_path, options); 

     _image.setImageBitmap(bitmap); 

     _field.setVisibility(View.GONE); 

     //_path = path to the image to be OCRed 
     ExifInterface exif = new ExifInterface(_path); 
     int exifOrientation = exif.getAttributeInt(
       ExifInterface.TAG_ORIENTATION, 
       ExifInterface.ORIENTATION_NORMAL); 

     int rotate = 0; 

     switch (exifOrientation) { 
      case ExifInterface.ORIENTATION_ROTATE_90: 
       rotate = 90; 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_180: 
       rotate = 180; 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_270: 
       rotate = 270; 
       break; 
     } 

     if (rotate != 0) { 
      int w = bitmap.getWidth(); 
      int h = bitmap.getHeight(); 

      // Setting pre rotate 
      Matrix mtx = new Matrix(); 
      mtx.preRotate(rotate); 

      // Rotating Bitmap & convert to ARGB_8888, required by tess 
      bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false); 
      bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); 
     } 

     TessBaseAPI baseApi = new TessBaseAPI(); 
     // DATA_PATH = Path to the storage 
     // lang for which the language data exists, usually "eng" 
     baseApi.init(""sdcard/tesseract/tessdata", "eng"); 
     baseApi.setImage(bitmap); 
     String recognizedText = baseApi.getUTF8Text(); 
     System.out.println(recognizedText); 
     baseApi.end(); 
    } 

    @Override 
    protected void onRestoreInstanceState(Bundle savedInstanceState){ 
     Log.i("MakeMachine", "onRestoreInstanceState()"); 
     if(savedInstanceState.getBoolean(PitterActivity.PHOTO_TAKEN)) { 
      try { 
       onPhotoTaken(); 
      } 
      catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     outState.putBoolean(PitterActivity.PHOTO_TAKEN, _taken); 
    } 
} 

这是日志:

10-13 23:13:51.191: I/MakeMachine(29787): ButtonClickHandler.onClick() 
10-13 23:13:51.191: I/MakeMachine(29787): startCameraActivity() 
10-13 23:13:51.851: D/CLIPBOARD(29787): Hide Clipboard dialog at Starting input: finished by someone else... ! 
10-13 23:13:51.866: W/IInputConnectionWrapper(29787): showStatusIcon on inactive InputConnection 
10-13 23:14:07.431: I/MakeMachine(29787): onRestoreInstanceState() 
10-13 23:14:07.431: I/MakeMachine(29787): resultCode: -1 
10-13 23:14:07.431: I/MakeMachine(29787): onPhotoTaken 
10-13 23:14:07.431: I/System.out(29787): Not a DRM File, opening notmally 
10-13 23:14:07.436: E/JHEAD(29787): can't open 
10-13 23:14:07.436: D/dalvikvm(29787): Trying to load lib /data/data/com.mmm.pitter/lib/liblept.so 0x4154e9a0 
10-13 23:14:07.436: D/dalvikvm(29787): Added shared lib /data/data/com.mmm.pitter/lib/liblept.so 0x4154e9a0 
10-13 23:14:07.446: D/dalvikvm(29787): Trying to load lib /data/data/com.mmm.pitter/lib/libtess.so 0x4154e9a0 
10-13 23:14:07.456: D/dalvikvm(29787): Added shared lib /data/data/com.mmm.pitter/lib/libtess.so 0x4154e9a0 
10-13 23:14:07.471: D/AndroidRuntime(29787): Shutting down VM 
10-13 23:14:07.471: W/dalvikvm(29787): threadid=1: thread exiting with uncaught exception (group=0x40c5b1f8) 
10-13 23:14:07.476: E/AndroidRuntime(29787): FATAL EXCEPTION: main 
10-13 23:14:07.476: E/AndroidRuntime(29787): java.lang.RuntimeException: Unable to resume activity {com.mmm.pitter/com.mmm.pitter.PitterActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=null} to activity {com.mmm.pitter/com.mmm.pitter.PitterActivity}: java.lang.IllegalArgumentException: Data path must contain subfolder tessdata! 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2456) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2484) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1998) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3363) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at android.app.ActivityThread.access$700(ActivityThread.java:127) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1163) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at android.os.Handler.dispatchMessage(Handler.java:99) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at android.os.Looper.loop(Looper.java:137) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at android.app.ActivityThread.main(ActivityThread.java:4507) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at java.lang.reflect.Method.invokeNative(Native Method) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at java.lang.reflect.Method.invoke(Method.java:511) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at dalvik.system.NativeStart.main(Native Method) 
10-13 23:14:07.476: E/AndroidRuntime(29787): Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=null} to activity {com.mmm.pitter/com.mmm.pitter.PitterActivity}: java.lang.IllegalArgumentException: Data path must contain subfolder tessdata! 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at android.app.ActivityThread.deliverResults(ActivityThread.java:2992) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2443) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  ... 13 more 
10-13 23:14:07.476: E/AndroidRuntime(29787): Caused by: java.lang.IllegalArgumentException: Data path must contain subfolder tessdata! 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at com.googlecode.tesseract.android.TessBaseAPI.init(TessBaseAPI.java:178) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at com.mmm.pitter.PitterActivity.onPhotoTaken(PitterActivity.java:146) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at com.mmm.pitter.PitterActivity.onActivityResult(PitterActivity.java:88) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at android.app.Activity.dispatchActivityResult(Activity.java:4649) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  at android.app.ActivityThread.deliverResults(ActivityThread.java:2988) 
10-13 23:14:07.476: E/AndroidRuntime(29787):  ... 14 more 
10-13 23:19:32.376: I/Process(29787): Sending signal. PID: 29787 SIG: 9 
+0

在您的某个例外消息的末尾是否会执行此操作?“数据路径必须包含子文件夹tessdata!” – mfrankli

+0

我已将数据路径更改为148行的子文件夹tessdata,但它仍然表示它必须包含它。我需要在哪里更改它 –

+0

我应该在哪里添加tessdata文件夹。?在库或资产。? – Frankenstein

回答

11

你需要把数据文件在tessdata目录,并指定父目录tessdata在您的init()方法:

baseApi.init("/mnt/sdcard/tesseract", "eng"); 
+0

你可以PLZ提供活动XML文件? –

+0

我应该在哪里添加tessdata文件夹。?在库或资产。? – Frankenstein

+0

@Frankenstein:我一直在“assests” – sUndeep

-2

tesseract库是作为.zip for windows用作.tar.gz for linux用户的。

baseApi.init("/mnt/sdcard/tesseract/tessdata/eng.traineddata", "eng"); 

请告诉我它是否适合您。

1
baseApi.init(""sdcard/tesseract/tessdata", "eng"); 

baseApi.init(""sdcard/tesseract/", "eng"); 

替换tessaract文件夹必须包括tessdata文件夹。因为在编译时,路径将在init()函数中添加“tessdat”与行

File tessdata = new File(datapath + "tessdata"); 

。 又为何在路径的末尾斜杠(“/”),在下面的评论将帮助您:

数据通路必须是tessdata的父目录的名称和 必须在/结束。最后的任何名字将被删除。 语言(通常)是ISO 639-3字符串或null将 默认为eng。它是完全安全的(并且最终也将是有效的 )在同一个实例上多次调用Init来更改 语言,或者只是重置分类器。

你可以在website看到init()函数的注释。 我希望他们会帮助你。