Ask Your Question
0

Illegal argument exception and thread issues on lockCanvas

asked 2018-08-30 23:22:15 -0600

bfialkoff gravatar image

updated 2018-08-31 00:38:43 -0600

I am attempting to take a picture, and in the onPictureTaken I atempt to make some layout changes and then pass the image data to a new activity. When making layout changes the app crashes with an illegal argument error that traces back to the CameraWorker thread running in JavaCameraView.

I know this is kind of long but I'm really stumped. I'd really appreciate any help.

The idea is like this: When the onPictureTaken is called i freeze the preview (to show the user the image he captured) and display an "ok" button and a "retry" button. However when I attempt to change the layout (i.e make the buttons visible) the app crashes wit the above error and the following stacktrace:

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:405)
                     at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:308)
                     at java.lang.Thread.run(Thread.java:818)

The methods are in CameraBridgeViewBase and are called via a thread that is running in JavaCameraView which is why I think this is a thread issue. Unfortunately I dont know where to go from here.

My methods that cause the crash are here:

@Override
    public void onPictureTaken(byte[] data, Camera camera) {
        Log.i(TAG, "Saving a bitmap to file");
        Toast.makeText(context,"Not Starting New Activity. Look at me now error!",Toast.LENGTH_LONG).show();;
        //attempt to export all this to JavaCameraView, i have a feeling that there is a conflict with his thread....maybe that will help
        buttonManager(data);

    }

    private void buttonManager(byte[] data) {
        //find buttons
        final byte[] img_data = data;
        final int width = this.getWidth();
        final int height = this.getHeight();

        okButton.setVisibility(View.VISIBLE);
        retryButton.setVisibility(View.VISIBLE);
        captureImageButton.setVisibility(View.GONE);


        okButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent startImgProc = new Intent(context,ImageProcessing.class);
                startImgProc.putExtra("image",img_data);
                startImgProc.putExtra("width",width);
                startImgProc.putExtra("height",height);
                disconnectCamera();
                context.startActivity(startImgProc);
                ((Activity) context).finish();
            }
        });

        retryButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                captureImageButton.setVisibility(View.VISIBLE);
                okButton.setVisibility(View.GONE);
                retryButton.setVisibility(View.GONE);
            }
        });
    }

The call to deliverAndDrawFrame is from JavaCameraView here:

private class CameraWorker implements Runnable {

        @Override
        public void run() {
            do {
                boolean hasFrame = false;
                synchronized (JavaCameraView.this) {
                    try {
                        while (!mCameraFrameReady && !mStopThread) {
                            JavaCameraView.this.wait();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (mCameraFrameReady)
                    {
                        mChainIdx = 1 - mChainIdx;
                        mCameraFrameReady = false;
                        hasFrame = true;
                    }
                }

                if (!mStopThread && hasFrame) {
                    if (!mFrameChain[1 - mChainIdx].empty())
                        deliverAndDrawFrame(mCameraFrame[1 - mChainIdx]);
                }
            } while (!mStopThread);
            Log.d(TAG, "Finish processing thread");
        }
    }

and the method itself

protected void deliverAndDrawFrame(CvCameraViewFrame frame) {
    Mat modified;

    if (mListener != null) {
        modified = mListener.onCameraFrame(frame);
    } else {
        modified = frame.rgba();
    }

    boolean bmpValid = true;
    if (modified != null) {
        try {
            Utils.matToBitmap(modified, mCacheBitmap);
        } catch(Exception e) {
            Log.e(TAG, "Mat type: " + modified);
            Log.e(TAG, "Bitmap type: " + mCacheBitmap.getWidth ...
(more)
edit retag flag offensive close merge delete

Comments

your SO link is useless here. if you're too lazy to give us the details HERE, probably noone will answer it.

berak gravatar imageberak ( 2018-08-31 00:02:57 -0600 )edit

There isn't a code format option here. I assumed that was the best alternative. Happy to provide details here. Coming right up.

bfialkoff gravatar imagebfialkoff ( 2018-08-31 00:21:45 -0600 )edit

"There isn't a code format option here." -- there is ! mark your code with mouse, and press crtl-k (or use the 10101 button)

berak gravatar imageberak ( 2018-08-31 00:23:25 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2018-08-31 00:27:27 -0600

bfialkoff gravatar image

Oops I missed that,thanks.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2018-08-30 23:22:15 -0600

Seen: 1,101 times

Last updated: Aug 31 '18