Ошибки при получении предварительного просмотра кадров с камеры - PullRequest
0 голосов
/ 02 апреля 2019

Я пытаюсь настроить камеру OpenCV с CvCameraViewListener2 и отдельный класс с моим OpenCameraView. Приложение работает, но я получаю сообщение об ошибке, пока камера получает кадры.

Вот моя CameraActivity, мой пользовательский OpenCameraView и ошибка, которая возникает при запуске камеры с помощью кнопки. Прошу прощения за публикацию такого большого количества кода, но я действительно не знаю, откуда эта ошибка.

public class CameraActivity extends AppCompatActivity implements CvCameraViewListener2 {

    private static final String TAG = CameraActivity.class.getSimpleName();
    public static final String SCAN_IMAGE_LOCATION = Environment.getExternalStorageDirectory() + File.separator + "OpenScanner";

    Context context;
    OpenCameraView jcv;
    Mat mRgba, des, forward, mGray;           // mat1, mat2, mat3
    Button picButton;
    int mViewMode;

    private BaseLoaderCallback baseLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS: {
                    jcv.enableView();
                    picButton.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            String outPicture = SCAN_IMAGE_LOCATION + File.separator + generateFilename();
                            createDefaultFolder(SCAN_IMAGE_LOCATION);

                            jcv.takePicture(outPicture);
                            Toast.makeText(CameraActivity.this, "Picture has been taken ", Toast.LENGTH_LONG).show();
                        }
                    });
                }
                break;
                default: {
                    super.onManagerConnected(status);
                }
                    break;
            }
        }
    };

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.i(TAG, "called onCreate");
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        setContentView(R.layout.activity_camera);

        picButton = findViewById(R.id.picButton);
        jcv = findViewById(R.id.camera_view);
        //jcv.setVisibility(CameraBridgeViewBase.VISIBLE);
        jcv.setCvCameraViewListener(this);

        jcv.setFocusMode(context, 6);

        jcv.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if(jcv != null) {

                }
                return false;
            }
        });
    }
    @Override
    public void onResume(){
        super.onResume();
        Log.d(TAG, "in onResume");

        if (OpenCVLoader.initDebug()) {
            Log.d(TAG, "OpenCV library found inside package. Using it!");
            baseLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
        } else {
            Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, baseLoaderCallback);
        }
    }

    @Override
    public void onCameraViewStarted(int width, int height) {
        Log.d(TAG, "in onCameraViewStarted");
        mRgba = new Mat(height, width, CvType.CV_8UC4);
//        mGray = new Mat(height, width, CvType.CV_8UC1);
//        des = new Mat(height, width, CvType.CV_8UC4);
//        forward = new Mat(height, width, CvType.CV_8UC4);
    }

    @Override
    public Mat onCameraFrame(final CvCameraViewFrame inputFrame) {
        Log.d(TAG, "in onCameraFrame");
        mRgba = inputFrame.rgba();
        //mGray = inputFrame.gray();      // grayscale required for detection
        return mRgba;

    }


    // Nicht mehr ändern
    @Override
    public void onPause() {
        super.onPause();
        if (jcv != null) {
            jcv.disableView();
        }
    }
    // Nicht mehr ändern
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (jcv != null)
            jcv.disableView();
    }


    @Override
    public void onCameraViewStopped() {
    }


    public static void createDefaultFolder(String dirPath){
        File directory = new File(dirPath);
        if(!directory.exists()){
            directory.mkdir();
        }
    }

    public static String generateFilename(){
        @SuppressLint("SimpleDateFormat") SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
        return "scan" + sdf.format(new Date()) + ".jpg";
    }
}

public class OpenCameraView extends JavaCameraView implements Camera.PictureCallback {

    private static final String TAG = OpenCameraView.class.getSimpleName();
    private String mPictureFileName;

    public OpenCameraView(Context context, AttributeSet attrs) {
        super(context, attrs);
        Log.d(TAG, "in OpenCameraView Constructor");
    }

    public void setFocusMode(Context item, int type) {

        mCamera = Camera.open();
        mCamera.startPreview();
        Parameters params = mCamera.getParameters();
        List<String> FocusModes = params.getSupportedFocusModes();
        if(FocusModes != null && FocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
            Log.d(TAG, "Phone supports autofocus :)");
        }
        else {
            Log.d(TAG, "Phone does not support autofocus :(");
        }

        mCamera.cancelAutoFocus();
        mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean b, Camera camera) {
            }
        });

        switch (type) {
            case 0:
                if (FocusModes.contains(Parameters.FOCUS_MODE_AUTO))
                    params.setFocusMode(Parameters.FOCUS_MODE_AUTO);
                else
                    Toast.makeText(item, "Auto Mode is not supported", Toast.LENGTH_SHORT).show();
                break;
            case 1:
                if (FocusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
                    params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
                else
                    Toast.makeText(item, "Continuous Mode is not supported", Toast.LENGTH_SHORT).show();
                break;
            case 2:
                if (FocusModes.contains(Parameters.FOCUS_MODE_EDOF))
                    params.setFocusMode(Parameters.FOCUS_MODE_EDOF);
                else
                    Toast.makeText(item, "EDOF Mode is not supported", Toast.LENGTH_SHORT).show();
                break;
            case 3:
                if (FocusModes.contains(Parameters.FOCUS_MODE_FIXED))
                    params.setFocusMode(Parameters.FOCUS_MODE_FIXED);
                else
                    Toast.makeText(item, "Fixed Mode is not supported", Toast.LENGTH_SHORT).show();
                break;
            case 4:
                if (FocusModes.contains(Parameters.FOCUS_MODE_INFINITY))
                    params.setFocusMode(Parameters.FOCUS_MODE_INFINITY);
                else
                    Toast.makeText(item, "Infinity Mode is not supported", Toast.LENGTH_SHORT).show();
                break;
            case 5:
                if (FocusModes.contains(Parameters.FOCUS_MODE_MACRO))
                    params.setFocusMode(Parameters.FOCUS_MODE_MACRO);
                else
                    Toast.makeText(item, "Macro Mode is not supported", Toast.LENGTH_SHORT).show();
                break;
            case 6:
                if (FocusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
                    params.setFocusMode((Parameters.FOCUS_MODE_CONTINUOUS_PICTURE));
                else
                    Toast.makeText(item, "Continuous picture mode is not supported", Toast.LENGTH_SHORT).show();
                break;
        }

        mCamera.setParameters(params);
    }

    public void takePicture(final String fileName) {
        Log.i(TAG, "Taking picture");
        this.mPictureFileName = fileName;
        mCamera.setPreviewCallback(null);
        mCamera.takePicture(null, null, this);
    }

    @SuppressLint("WrongThread")
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        Log.i(TAG, "Saving a bitmap to file");
        // The camera preview was automatically stopped. Start it again.
        mCamera.startPreview();
        mCamera.setPreviewCallback(this);

        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        Uri uri = Uri.parse(mPictureFileName);

        Log.d(TAG, "selectedImage: " + uri);
        Bitmap bm = null;
        bm = rotate(bitmap, 90);

        // Write the image in a file (in jpeg format)
        try {
            FileOutputStream fos = new FileOutputStream(mPictureFileName);
            bm.compress(Bitmap.CompressFormat.JPEG, 80, fos);
            fos.close();

        } catch (java.io.IOException e) {
            Log.e("PictureDemo", "Exception in photoCallback", e);
        }
    }

    private static Bitmap rotate(Bitmap bm, int rotation) {
        if (rotation != 0) {
            Matrix matrix = new Matrix();
            matrix.postRotate(rotation);
            Bitmap bmOut = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
            return bmOut;
        }
        return bm;
    }
}
I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@6fec3c1 time:559599005
V/ActivityThread: updateVisibility : ActivityRecord{d2268f token=android.os.BinderProxy@8e64234 {com.example.myapplication/com.example.myapplication.MainActivity}} show : false
D/JavaCameraView: Preview Frame received. Frame size: 2332800
D/CameraActivity: in onCameraFrame
D/JavaCameraView: Preview Frame received. Frame size: 2332800
E/SurfaceHolder: Exception locking surface
    java.lang.IllegalArgumentException
        at android.view.Surface.nativeLockCanvas(Native Method)
        at android.view.Surface.lockCanvas(Surface.java:267)
        at android.view.SurfaceView$4.internalLockCanvas(SurfaceView.java:973)
        at android.view.SurfaceView$4.lockCanvas(SurfaceView.java:941)
        at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:410)
        at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:395)
        at java.lang.Thread.run(Thread.java:818)
D/CameraActivity: in onCameraFrame
D/JavaCameraView: Preview Frame received. Frame size: 2332800
E/SurfaceHolder: Exception locking surface
    java.lang.IllegalArgumentException
        at android.view.Surface.nativeLockCanvas(Native Method)
        at android.view.Surface.lockCanvas(Surface.java:267)
        at android.view.SurfaceView$4.internalLockCanvas(SurfaceView.java:973)
        at android.view.SurfaceView$4.lockCanvas(SurfaceView.java:941)
        at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:410)
        at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:395)
        at java.lang.Thread.run(Thread.java:818)
D/JavaCameraView: Preview Frame received. Frame size: 2332800
D/JavaCameraView: Preview Frame received. Frame size: 2332800
D/CameraActivity: in onCameraFrame
E/SurfaceHolder: Exception locking surface
    java.lang.IllegalArgumentException
        at android.view.Surface.nativeLockCanvas(Native Method)
        at android.view.Surface.lockCanvas(Surface.java:267)
        at android.view.SurfaceView$4.internalLockCanvas(SurfaceView.java:973)
        at android.view.SurfaceView$4.lockCanvas(SurfaceView.java:941)
        at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:410)
        at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:395)
        at java.lang.Thread.run(Thread.java:818)
...