2016-06-30 8 views
3

私は現在、アクティビティタブ(Androidのフラグメント)を切り替えることができる最初のアプリケーションを開発中です。私は4つのタブを持っており、タブの1つでは、文字認識(OCR)のための画像認識を実装しています。私はPriyank Vermaによって作られたEasy OCR Libraryと呼ばれる簡略化されたOCR Tesseractライブラリを使用しました。私はそのライブラリのサンプルをテストしています。しかし、自分のアプリケーション用にライブラリを使用すると、正しく動作しません。OCRスキャンでスキャン出力が表示されない

私のアプリのタブの1つに、私の電話カメラを使って写真を撮るための「スキャン」ボタンがあります。画像が撮影された後、私のアプリは保存されたディレクトリのキャプチャされた画像を文字認識のためにスキャンする必要があります。次に、私のアプリは以前の「スキャン」タブに戻り、そのタブの「スキャン」ボタンの上に文字認識の出力を表示します。そしてそれだけで、私のアプリはスキャンしていないようです。本当の問題は、画像が撮影された後に、&が保存されていることです。私のアプリは出力なしでタブに戻ります。私のコードは動作するはずですが、残念ながらそれはしません。何のエラーも、何もない、何が間違っているかを理解するために、私は何日も心を失いつつある。 ----------

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.kaydarinapp.queueappv2"> 
    <!-- Save file permission --> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
    <!-- Read file permission --> 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
    <!-- Camera permission --> 
    <uses-feature android:name="android.hardware.camera" /> 
    <uses-permission android:name="android.permission.CAMERA" /> 
    <!-- Internet permission --> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
     <activity android:name=".MainActivity" 
      android:screenOrientation="portrait" 
      android:configChanges="keyboardHidden|orientation|screenSize"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

----------私のアプリのマニフェスト

---- - :

ここでは、コードです------私のアプリのタブから----------

MyタブのXML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" 
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".Tab2" 
    android:gravity="center_horizontal" 
    > 

    <TextView android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/textView" 
     android:layout_marginTop="45dp" 
     android:layout_gravity="center_horizontal" 
     android:textSize="8pt" 
     /> 


    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/button" 
     android:layout_marginTop="20dp" 
     android:text="Scan" 
     android:layout_gravity="center_vertical" /> 

</LinearLayout> 

MyタブのJava簡単OCRライブラリから

package com.kaydarinapp.queueappv2; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.content.Intent; 
import android.content.pm.PackageManager; 
import android.graphics.Bitmap; 
import android.hardware.Camera; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentActivity; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Button; 
import android.widget.FrameLayout; 
import android.widget.LinearLayout; 
import android.widget.TextView; 

import com.wordpress.priyankvex.easyocrscannerdemo.Config; 
import com.wordpress.priyankvex.easyocrscannerdemo.EasyOcrScanner; 
import com.wordpress.priyankvex.easyocrscannerdemo.EasyOcrScannerListener; 

/** 
* Created by Kaydarin on 6/1/2016. 
*/ 

//Our class extending fragment 
public class Tab2 extends Fragment implements EasyOcrScannerListener { 

    private LinearLayout linearLayout; 
    private FragmentActivity fragActivity; 
    EasyOcrScanner mEasyOcrScanner; 
    TextView textView; 
    ProgressDialog mProgressDialog; 
    Button btnCapture; 

    //Overriden method onCreateView 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     fragActivity = super.getActivity(); 
     linearLayout = (LinearLayout) inflater.inflate(R.layout.tab2, container, false); 

     textView = (TextView) fragActivity.findViewById(R.id.textView); 

     // initialize EasyOcrScanner instance. 
     mEasyOcrScanner = new EasyOcrScanner(getActivity(), "EasyOcrScanner", 
       Config.REQUEST_CODE_CAPTURE_IMAGE, "eng"); 

     // Set ocrScannerListener 
     mEasyOcrScanner.setOcrScannerListener(this); 

     btnCapture = (Button) linearLayout.findViewById(R.id.button); 
     btnCapture.setOnClickListener(new View.OnClickListener(){ 
      @Override 
      public void onClick(View v) { 
       mEasyOcrScanner.takePicture(); 
      } 
     }); 

     return linearLayout; 
    } 

    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     // Call onImageTaken() in onActivityResult. 
     if (resultCode == getActivity().RESULT_OK && requestCode == Config.REQUEST_CODE_CAPTURE_IMAGE){ 
      mEasyOcrScanner.onImageTaken(); 
     } 
    } 

    /** 
    * Callback when after taking picture, scanning process starts. 
    * Good place to show a progress dialog. 
    * @param filePath file path of the image file being processed. 
    */ 
    @Override 
    public void onOcrScanStarted(String filePath) { 
     mProgressDialog = new ProgressDialog(getActivity()); 
     mProgressDialog.setMessage("Scanning..."); 
     mProgressDialog.show(); 
    } 

    /** 
    * Callback when scanning is finished. 
    * Good place to hide teh progress dialog. 
    * @param bitmap Bitmap of image that was scanned. 
    * @param recognizedText Scanned text. 
    */ 
    @Override 
    public void onOcrScanFinished(Bitmap bitmap, String recognizedText) { 
     textView.setText(recognizedText); 
     if (mProgressDialog.isShowing()){ 
      mProgressDialog.dismiss(); 
     } 
    } 
} 

---------- ----------

簡単OCRライブラリのマニフェスト

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.wordpress.priyankvex.easyocrscanner"> 

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.CAMERA"/> 

</manifest> 

コンフィグJavaの

package com.wordpress.priyankvex.easyocrscannerdemo; 

/** 
* Created by Priyank(@priyankvex) on 27/8/15. 
*/ 
public class Config { 

    public static String TAG = "OcrScanner"; 
    public static int REQUEST_CODE_CAPTURE_IMAGE = 1995; 

} 

EasyOCRScannerListenerのJava

package com.wordpress.priyankvex.easyocrscannerdemo; 

import android.graphics.Bitmap; 

/** 
* Created by Priyank(@priyankvex) on 27/8/15. 
* 
* Interface for the callbacks for {@link EasyOcrScanner}. 
*/ 
public interface EasyOcrScannerListener { 

    public void onOcrScanStarted(String filePath); 

    public void onOcrScanFinished(Bitmap bitmap, String recognizedText); 
} 

EasyOCRScannerのJava

package com.wordpress.priyankvex.easyocrscannerdemo; 

import android.app.Activity; 
import android.content.Intent; 
import android.net.Uri; 
import android.util.Log; 

import java.io.File; 
import java.util.Calendar; 

/** 
* Created by Priyank(@priyankvex) on 27/8/15. 
* 
* Class to handle scanning of image. 
*/ 
public class EasyOcrScanner { 

    protected Activity mActivity; 
    private String directoryPathOriginal; 
    private String filePathOriginal; 
    private int requestCode; 
    private EasyOcrScannerListener mOcrScannerListener; 
    private String trainedDataCode; 

    public EasyOcrScanner(Activity activity, String directoryPath, int requestCode, String trainedDataCode){ 
     this.mActivity = activity; 
     this.directoryPathOriginal = directoryPath; 
     this.requestCode = requestCode; 
     this.trainedDataCode = trainedDataCode; 
    } 

    public void takePicture(){ 
     Intent e = new Intent("android.media.action.IMAGE_CAPTURE"); 
     this.filePathOriginal = FileUtils.getDirectory(this.directoryPathOriginal) + File.separator + Calendar.getInstance().getTimeInMillis() + ".jpg"; 
     e.putExtra("output", Uri.fromFile(new File(this.filePathOriginal))); 

     startActivity(e); 
    } 

    public void onImageTaken(){ 
     Log.d(Config.TAG, "onImageTaken with path " + this.filePathOriginal); 
     ImageProcessingThread thread = new ImageProcessingThread(this.mOcrScannerListener, 
       this.filePathOriginal, this.directoryPathOriginal, this.mActivity, this.trainedDataCode); 
     thread.execute(); 
    } 

    private void startActivity(Intent intent){ 
     if(this.mActivity != null) { 
      this.mActivity.startActivityForResult(intent, this.requestCode); 
     } 
    } 

    public void setOcrScannerListener(EasyOcrScannerListener mOcrScannerListener) { 
     this.mOcrScannerListener = mOcrScannerListener; 
    } 


} 

のfileutilsのJava

package com.wordpress.priyankvex.easyocrscannerdemo; 

import android.os.Environment; 
import android.util.Log; 

import java.io.File; 

/** 
* Created by Priyank(@priyankvex) on 27/8/15. 
*/ 
public class FileUtils { 

    public static String getDirectory(String folderName) { 
     File directory = null; 
     directory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + folderName); 
     if(!directory.exists()) { 
      directory.mkdirs(); 
     } 

     return directory.getAbsolutePath(); 
    } 

    public static String getTessdataDirectory(String directoryPath){ 
     File tessdataDirectory = new File(directoryPath + "/tessdata"); 
     if (tessdataDirectory.mkdirs()){ 
      Log.d(Config.TAG, "tessdata directory created"); 
     } 
     return tessdataDirectory.getAbsolutePath(); 
    } 
} 

ImageProcessingThreadのJava

package com.wordpress.priyankvex.easyocrscannerdemo; 

import android.app.Activity; 
import android.content.res.AssetManager; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Matrix; 
import android.media.ExifInterface; 
import android.os.AsyncTask; 
import android.util.Log; 

import com.googlecode.tesseract.android.TessBaseAPI; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 

/** 
* Created by Priyank(@priyankvex) on 27/8/15. 
* 
* Async Task to process the image and scan the image using tesseract library. 
* Equipped with proper callbacks. 
*/ 
public class ImageProcessingThread extends AsyncTask<Void, Void, Void> { 

    private EasyOcrScannerListener mOcrScannerListener; 
    private String filePath; 
    private Bitmap mBitmap; 
    private String scannedText; 
    // trained data file used by Tesseract will be copied in directoryPath/tessdata 
    private String directoryPath; 
    private String absoluteDirectoryPath; 
    private Activity mActivity; 
    String trainedDataCode; 

    public ImageProcessingThread(EasyOcrScannerListener ocrScannerListener, String filePath, 
           String directoryPath, Activity activity, String trainedDataCode) { 
     this.mOcrScannerListener = ocrScannerListener; 
     this.filePath = filePath; 
     this.directoryPath = directoryPath; 
     this.absoluteDirectoryPath = FileUtils.getDirectory(this.directoryPath); 
     this.mActivity = activity; 
     this.trainedDataCode = trainedDataCode; 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     mOcrScannerListener.onOcrScanStarted(this.filePath); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     processImage(); 
     makeTessdataReady(); 
     scannedText = scanImage(); 
     Log.d(Config.TAG, "Scanned test : " + scannedText); 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void aVoid) { 
     super.onPostExecute(aVoid); 
     mOcrScannerListener.onOcrScanFinished(mBitmap, scannedText); 
    } 

    private void processImage() { 
     int imageOrientationCode = getImageOrientation(); 
     Bitmap rawBitmap = getBitmapFromPath(); 
     // Getting the bitmap in right orientation. 
     this.mBitmap = rotateBitmap(rawBitmap, imageOrientationCode); 
    } 

    private Bitmap getBitmapFromPath() { 
     BitmapFactory.Options bmOptions = new BitmapFactory.Options(); 
     bmOptions.inSampleSize = 4; 
     Bitmap bitmap = BitmapFactory.decodeFile(this.filePath, bmOptions); 
     return bitmap; 
    } 

    private int getImageOrientation() { 
     ExifInterface exif = null; 
     try { 
      exif = new ExifInterface(this.filePath); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     assert exif != null; 
     int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 
       ExifInterface.ORIENTATION_UNDEFINED); 
     return orientation; 
    } 

    private Bitmap rotateBitmap(Bitmap bitmap, int orientation){ 

     Matrix matrix = new Matrix(); 
     switch (orientation) { 
      case ExifInterface.ORIENTATION_NORMAL: 
       return bitmap; 
      case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: 
       matrix.setScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_180: 
       matrix.setRotate(180); 
       break; 
      case ExifInterface.ORIENTATION_FLIP_VERTICAL: 
       matrix.setRotate(180); 
       matrix.postScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_TRANSPOSE: 
       matrix.setRotate(90); 
       matrix.postScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_90: 
       matrix.setRotate(90); 
       break; 
      case ExifInterface.ORIENTATION_TRANSVERSE: 
       matrix.setRotate(-90); 
       matrix.postScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_270: 
       matrix.setRotate(-90); 
       break; 
      default: 
       return bitmap; 
     } 
     try { 
      Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 
      bitmap.recycle(); 
      return bmRotated; 
     } 
     catch (OutOfMemoryError e) { 
      e.printStackTrace(); 
      return null; 
     } 
    } 

    private String scanImage(){ 
     TessBaseAPI baseApi = new TessBaseAPI(); 
     Log.d(Config.TAG, "Data path : " + FileUtils.getDirectory(this.directoryPath)); 
     baseApi.init(FileUtils.getDirectory(this.directoryPath) + "/", this.trainedDataCode); 
     baseApi.setImage(this.mBitmap); 
     String recognizedText = baseApi.getUTF8Text(); 
     baseApi.end(); 

     return recognizedText; 
    } 

    private void makeTessdataReady(){ 

     // created test data directory if necessary under absoluteDirectoryPath and returns its absolute path. 
     String tessdirectoryPath = FileUtils.getTessdataDirectory(this.absoluteDirectoryPath); 

     if (!(new File(tessdirectoryPath+ "/" + this.trainedDataCode + ".traineddata")).exists()) { 
      try { 

       AssetManager assetManager = mActivity.getAssets(); 
       InputStream in = assetManager.open("tessdata/" + this.trainedDataCode + ".traineddata"); 
       //GZIPInputStream gin = new GZIPInputStream(in); 
       // Output stream with the location where we have to write the eng.traineddata file. 
       OutputStream out = new FileOutputStream(tessdirectoryPath + "/" + this.trainedDataCode 
         + ".traineddata"); 

       // Transfer bytes from in to out 
       byte[] buf = new byte[1024]; 
       int len; 
       //while ((lenf = gin.read(buff)) > 0) { 
       while ((len = in.read(buf)) > 0) { 
        out.write(buf, 0, len); 
       } 
       in.close(); 
       //gin.close(); 
       out.close(); 

       Log.v(Config.TAG, "Copied " + " traineddata"); 
      } catch (IOException e) { 
       Log.e(Config.TAG, "Was unable to copy " + " traineddata " + e.toString()); 
      } 
     } 
     else{ 
      Log.d(Config.TAG, "tessdata already present"); 
     } 
    } 

} 

私はあなたたちが私を助けることができると思います。このコードの何が間違っているかを理解する日が来た.......

+0

あなたは成功したアンドロイドスタジオでたTesseractのlibが実行しているのですか? –

+0

@SagarNayak tesseract libを実行するとどういう意味ですか?私はそこで私のアプリケーションを実行することができますし、 ''プロジェクトをコンパイルする( ':tess-two') ''プロジェクトをコンパイルする( ':easy_ocr_library') 'をプロジェクトのgradleに含めました。さらに、そこにあるサンプルアプリケーションが動作し、私はウェブ上のリソースからすべてのガイダンスに従った。 – Kaydarin

+0

はい。私は同じことを求めています。あなたはtess-twoを構築するためにndkを使用しましたか? –

答えて

0

カメラアクティビティがRESULT_OKではなくRESULT_CANCELEDを返すというのは問題だと思うので、tesseractは決して呼び出されません。これを確認できます。 g。 「onActivityResult」メソッドの開始時に「Tab2.java」に追加することによって:

Log.d("PictureEdit", "onActivityResult w/ resultCode=" + resultCode + " (is ok: " + (resultCode == RESULT_OK) + " is canceled: " + (resultCode == RESULT_CANCELED) + ")" + " requestCode=" + requestCode); 

なぜそうでしょうか? Android 6(Marshmallow)から始めるので、マニフェストに必要な権限を宣言するだけでは不十分です。さらに、アクセス権は実行時にユーザーから取得する必要があります。

こちらを参照してください:ここでhttps://developer.android.com/training/permissions/requesting.html

は、私がカメラとR /外部ストレージへワットへのアクセス権を取得するために使用するコードです:

private void checkPermissions(){ 
    if (Build.VERSION.SDK_INT >= 23) { 
     boolean needWriteExtStorage = checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) 
       != PackageManager.PERMISSION_GRANTED; 
     boolean needCamera = checkSelfPermission(android.Manifest.permission.CAMERA) 
       != PackageManager.PERMISSION_GRANTED; 
     if (needWriteExtStorage || needCamera){ 
      String[] permissions = new String[((needWriteExtStorage)?(1):(0)) + ((needCamera)?(1):(0))]; 
      int idx = 0; 
      if (needWriteExtStorage){ 
       permissions[idx] = android.Manifest.permission.WRITE_EXTERNAL_STORAGE; 
       idx++; 
      } 
      if (needCamera){ 
       permissions[idx] = android.Manifest.permission.CAMERA; 
       idx++; 
      } 
      ActivityCompat.requestPermissions(
        this, permissions, 1); 
     } 
    } else { 
     //permission is automatically granted on sdk<23 upon installation 
     //Log.e("testing", "Permission is already granted"); 
    } 
} 
関連する問題