Android 位图致命信号 11 (SIGSEGV)

标签 android bitmap ocr

我正在开发一个 Android 应用程序,可以拍照并对其进行 OCRed。
如果不更改我的代码,我有时会遇到此错误,

错误:01-08 20:41:59.940: A/libc(10967):0x00000000 (code=1) 处的致命信号 11 (SIGSEGV)

我有一种方法可以裁剪图像让用户突出显示文本:

private void performCrop(){

    File file = new File(_path);
    Uri outputFileUri = Uri.fromFile(file);

    try{

        //call the standard crop action intent (the user device may not support it)
        Intent cropIntent = new Intent("com.android.camera.action.CROP");
        cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
        //indicate image type and Uri
        cropIntent.setDataAndType(picUri, "image/*");
        //set crop properties
        cropIntent.putExtra("crop", "true");
        //indicate aspect of desired crop
        cropIntent.putExtra("aspectX", 5);
        cropIntent.putExtra("aspectY", 1);
        //indicate output X and Y
        cropIntent.putExtra("outputX", 500);
        cropIntent.putExtra("outputY", 100);
        //retrieve data on return
        cropIntent.putExtra("return-data", true);
        //start the activity - we handle returning in onActivityResult
        startActivityForResult(cropIntent, 2);

    }catch(ActivityNotFoundException anfe){
         //display an error message
         String errorMessage = "Whoops - your device doesn't support the crop action!";
         Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
         toast.show();
    } catch (Exception ex) {
        Log.v(TAG, ex.toString());
    }
}

这是执行 OCR 的方法:

protected void onPhotoTaken() {
    _taken = true;

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

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

    try {
        ExifInterface exif = new ExifInterface(_path);
        int exifOrientation = exif.getAttributeInt(
                ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);

        Log.v(TAG, "Orient: " + exifOrientation);

        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;
        }

        Log.v(TAG, "Rotation: " + rotate);

        if (rotate != 0) {

            // Getting width & height of the given image.
            int w = bitmap.getWidth();
            int h = bitmap.getHeight();

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

            // Rotating Bitmap
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
        }

        // Convert to ARGB_8888, required by tess
        bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);

    } catch (IOException e) {
        Log.e(TAG, "Couldn't correct orientation: " + e.toString());
    }

    // _image.setImageBitmap( bitmap );

    Log.v(TAG, "Before baseApi");

    TessBaseAPI baseApi = new TessBaseAPI();
    baseApi.setDebug(true);
    baseApi.init(DATA_PATH, lang);
    baseApi.setImage(bitmap);

    String recognizedText = baseApi.getUTF8Text();

    baseApi.end();

    // You now have the text in recognizedText var, you can do anything with it.
    // We will display a stripped out trimmed alpha-numeric version of it (if lang is eng)
    // so that garbage doesn't make it to the display.

    Log.v(TAG, "OCRED TEXT: " + recognizedText);

    if ( lang.equalsIgnoreCase("eng") ) {
        recognizedText = recognizedText.replaceAll("[^a-zA-Z0-9]+", " ");
    }

    recognizedText = recognizedText.trim();

    if ( recognizedText.length() != 0 ) {
        _field.setText(_field.getText().toString().length() == 0 ? recognizedText : _field.getText() + " " + recognizedText);
        _field.setSelection(_field.getText().toString().length());
    }

    // Cycle done.
}

最佳答案

一个建议是 ExifInterface 初始化问题。

ExifInterface 的构造函数有一个严重的错误。 它不会检查参数文件名字符串是否为 null,也不会抛出异常,因此 JNI 崩溃会导致 SIGSEGV。

以下帖子会对你有所帮助(抱歉,这篇帖子是日文的...) http://alpha.mixi.co.jp/2013/11572/ http://alpha.mixi.co.jp/images/android-compat-jni-crash-exif.png

因此您应该在初始化 ExifInterface 对象之前检查 _path 值。

关于Android 位图致命信号 11 (SIGSEGV),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14221136/

相关文章:

android - 关于图像和文件夹

java - 如何强制键盘出现?

Android - 多次使用图像资源但仅在 1 个实例上更改 alpha

java - 在 android 中暂停一个类并开始另一个类,反之亦然

image-processing - 图像处理以提高 tesseract OCR 准确性

android - 带有 TextView 和切换按钮 i= 的 ListView 实现

android - Android SDK 中可用的所有 "android.intent.action"操作的详尽列表是什么?

c# - 从 RGB 格式的文件加载位图(无 Alpha)

php - 如何使用 OCR (TesseractOCR) php 库

python - 识别并提取 PDF 文档的特定部分