我正在尝试从手机的相机拍摄照片,然后将其传递给tesseract引擎,并通过您在下面看到的代码将结果写在文本视图中。
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());
}
}
}
但我收到此错误消息:
java.lang.RuntimeException: Failed to read bitmap
在这行代码中:
mTess.setImage(bitmap);
为什么会发生这种情况,我该如何解决? 我使用Windows 10和android studio 3.0.1与API 27和min API 21。
答案 0 :(得分:1)
此错误的原因是位图必须为非空或位图配置必须为ARGB_8888或无法从位图读取像素
mTess.setImage(bitmap);代码是
public
ReadFile.readBitmap(bmp);代码是
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();
}
我犯了一个错误,因为位图配置是RGB_565。