1

I am trying to take a photo from the phone's camera, then pass it to tesseract engine and write the result on a text view by the code you can see in the following.

MainActivity:

package com.example.arbazalam.myapplication;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.speech.tts.TextToSpeech;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {

    private MyTessOCR mTessOCR = new MyTessOCR(MainActivity.this);

    private Button takePictureButton;
    private ImageView imageView;

    int TAKE_PHOTO_CODE = 0;
    public static int count = 0;

    private TextView resultText;


    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTessOCR = new MyTessOCR(MainActivity.this);

        resultText = findViewById(R.id.textView_result);

        if (checkPermissions()){
            //  permissions  granted.

        }

        final String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/picFolder/";
        final File newdir = new File(dir);
        newdir.mkdirs();

        Button capture = findViewById(R.id.btnCapture);
        capture.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                count++;
                String file = dir+count+".jpg";
                File newfile = new File(file);
                try {
                    newfile.createNewFile();

                    Bitmap bitmap = BitmapFactory.decodeFile(file);
                    doOCR(bitmap);


                }
                catch (IOException e)
                {
                }

                Uri outputFileUri = FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID, newfile);

                Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

                startActivityForResult(cameraIntent, TAKE_PHOTO_CODE);
            }
        });


    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == TAKE_PHOTO_CODE && resultCode == RESULT_OK) {
            Log.d("CameraDemo", "Pic saved");
        }
    }





    public static final int MULTIPLE_PERMISSIONS = 10;

    String[] permissions= new String[]{
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA};
         //   Manifest.permission.ACCESS_COARSE_LOCATION,
          //  Manifest.permission.ACCESS_FINE_LOCATION};




    private  boolean checkPermissions() {
        int result;
        List<String> listPermissionsNeeded = new ArrayList<>();
        for (String p:permissions) {
            result = ContextCompat.checkSelfPermission(MainActivity.this,p);
            if (result != PackageManager.PERMISSION_GRANTED) {
                listPermissionsNeeded.add(p);
            }
        }
        if (!listPermissionsNeeded.isEmpty()) {
            ActivityCompat.requestPermissions(this, listPermissionsNeeded
                    .toArray(new String[listPermissionsNeeded.size()]),MULTIPLE_PERMISSIONS );
            return false;
        }
        return true;
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MULTIPLE_PERMISSIONS:{
                if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    // permissions granted.
                } else {
                    Toast.makeText(this, "Go to settings and enable permissions", Toast.LENGTH_LONG)
                            .show();
                    }
                    // permissions list of don't granted permission
                }
                return;
            }
        }



    private void doOCR(final Bitmap bitmap2) {
        String text = mTessOCR.getOCRResult(bitmap2);
        resultText.setText(text);

    }
}

MyTessOCR:

package com.example.arbazalam.myapplication;


import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.os.Environment;
import android.util.Log;

import com.googlecode.tesseract.android.TessBaseAPI;

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

public class MyTessOCR {
    private String datapath;
    private TessBaseAPI mTess;
    public Context context;

    public MyTessOCR(Context context)
    {
        this.context = context;
        datapath = Environment.getExternalStorageDirectory() + "/ocrctz/";
        File dir = new File(datapath + "/tessdata/");
        File file = new File(datapath + "/tessdata/" + "eng.traineddata");
        if (!file.exists())
        {
            Log.d("mylog", "in file doesn't exist");
            dir.mkdirs();
            copyFile(context);
        }

        mTess = new TessBaseAPI();
        String language = "eng";
        mTess.init(datapath, language);
        //Auto only
        mTess.setPageSegMode(TessBaseAPI.PageSegMode.PSM_AUTO_ONLY);
    }

    public void stopRecognition() {
        mTess.stop();
    }

    public String getOCRResult(Bitmap bitmap)
    {
        mTess.setImage(bitmap);
        String detected = mTess.getUTF8Text();
        return detected;
    }

    public void onDestroy()
    {
        if (mTess != null)
            mTess.end();
    }

    private void copyFile(Context context)
    {
        AssetManager assetManager = context.getAssets();
        try
        {   InputStream in = assetManager.open("eng.traineddata");
            OutputStream out = new FileOutputStream(datapath + "/tessdata/" + "eng.traineddata");
            byte[] buffer = new byte[1024];
            int read = in.read(buffer);
            while (read != -1) {
                out.write(buffer, 0, read);
                read = in.read(buffer);            }
        } catch (Exception e)
        {
            Log.d("mylog", "couldn't copy with the following error : "+e.toString());
        }
    }
}

But I get this error message:

java.lang.RuntimeException: Failed to read bitmap

On this line of the code:

mTess.setImage(bitmap);

Why this happens and how should I fix it? I use windows 10 and android studio 3.0.1 with the API 27 and min API 21.

1 Answer 1

1

The reason for this error is Bitmap must be non-null or Bitmap config must be ARGB_8888 or Failed to read pix from bitmap

mTess.setImage(bitmap); code is

public void setImage(Bitmap bmp) {
    if (mRecycled)
        throw new IllegalStateException();

    Pix image = ReadFile.readBitmap(bmp);

    if (image == null) {
        throw new RuntimeException("Failed to read bitmap");//Here's the log printed.
    }

    nativeSetImagePix(mNativeData, image.getNativePix());

    image.recycle();
}

ReadFile.readBitmap(bmp); code is

 public static Pix readBitmap(Bitmap bmp) {
    if (bmp == null) {
        Log.e(LOG_TAG, "Bitmap must be non-null");
        return null;
    }
    if (bmp.getConfig() != Bitmap.Config.ARGB_8888) {
        Log.e(LOG_TAG, "Bitmap config must be ARGB_8888");
        return null;
    }

    long nativePix = nativeReadBitmap(bmp);

    if (nativePix == 0) {
        Log.e(LOG_TAG, "Failed to read pix from bitmap");
        return null;
    }

    return new Pix(nativePix);
}

I made a mistake because bitmap config is RGB_565.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.