0

我有一个自定义的 OpenCV 相机活动,可以在点击屏幕时拍照。Activity 是带着一个startActivityForResultIntent 启动的,在 Activity 完成之后,照片的文件路径会交还给 MainActivity。但是,相机会异步保存照片,因此在拍摄照片之前不应检查文件路径。我正在使用文件路径来设置一个imageView,并立即调用它会给出一个空图像。我已经设法通过使用使其工作,Thread.sleep(3000);但这是一个可怕的选择,因为它只会停止 UI,正如我无数次阅读的那样,这是一个很大的禁忌!有没有办法可以等到照片保存后再调用返回MainActivity意图?我知道相机有回调,但我不明白它是如何工作的或如何使用它,也许这是最好的方法?

无论如何,这里有一些代码。

MainActivity extends FragmentActivity

rootView.findViewById(R.id.button_start_camera).setOnClickListener(new View.OnClickListener() {
                // Listen for Take Photo button Click, start app's openCV camera
                @Override
                public void onClick(View view) {
                    // Start Camera app
                    Intent intentCamera = new Intent(getActivity(), CameraActivity.class);
                    startActivityForResult(intentCamera, 2);
                }
            });

CameraActivity extends Activity implements CvCameraViewListener2, OnTouchListener

@Override
    public boolean onTouch(View v, MotionEvent event) {
        Log.i(TAG,"onTouch event");
        if (takePicture) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
            String currentDateandTime = sdf.format(new Date());
            fileName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath() +
                    "/MatCom_" + currentDateandTime + ".jpg";
            mOpenCvCameraView.takePicture(fileName);
            Toast.makeText(this, fileName + " saved", Toast.LENGTH_SHORT).show();
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Intent returnIntent = new Intent();
            returnIntent.putExtra("result", fileName);
            setResult(RESULT_OK, returnIntent);
            finish();
        }
            return false;
    }

然后回到MainActivity

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent)
    {
        super.onActivityResult(requestCode, resultCode, intent);
        Log.i(TAG, "onActivityResult. resultCode = " + requestCode);
        if (requestCode == 1) {//My other startActivityForResult...}

        if (requestCode == 131074 && resultCode == RESULT_OK){
            Bundle bundle = intent.getExtras();
            filepath = bundle.getString("result");
            Log.i(TAG, filepath);
            imageView = (ImageView) findViewById(R.id.imageView);
            bmp = BitmapFactory.decodeFile(filepath);
            imageView.setBackgroundResource(0);
            imageView.setImageBitmap(bmp);  
        }
    }

注意:顺便说一句,出于某种原因,尽管我将其设置为 2,但由于某种原因,我requestCode每次都会返回 131074 startActivityForResult- 如果您知道为什么会这样,请告诉我。

最后,如果有必要查看,这里是类中的takePicture方法CameraView

public void takePicture(final String fileName) {
        Log.i(TAG, "Taking picture");
        PictureCallback callback = new PictureCallback() {

            private String mPictureFileName = fileName;

            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                Log.i(TAG, "Saving a bitmap to file");
                Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length);
                try {
                    FileOutputStream out = new FileOutputStream(mPictureFileName);
                    picture.compress(Bitmap.CompressFormat.JPEG, 90, out);
                    picture.recycle();

                    // Open the image for analysis


                    // Read in the image from the file
                    Mat mOriginalImage = Highgui.imread(fileName);

                    // Only process the image if it actually exists!
                    if (mOriginalImage != null) {

                        // Find the size of the image
                        org.opencv.core.Size mSizeReadImage = mOriginalImage.size();

                        // From the number of rows and columns get the coordinates of the largest possible centralised square
                        double height = mSizeReadImage.height;
                        double width = mSizeReadImage.width;
                        double minDim = Math.min(height, width);
                        double top = height/2.0 - 2.0*minDim/5.0;
                        double left = width/2.0 - 2.0*minDim/5.0;

                        // Create a submat of the image based on the centralised square
                        Mat mOriginalImageSubmat = mOriginalImage.submat((int)Math.round(top), (int)Math.round(top + 4.0*minDim/5.0), (int)Math.round(left), (int)Math.round(left + 4.0*minDim/5.0));

                        // Create another Mat the required size but same type as mOriginalImageSubmat and resize mOriginalImageSubmat to fit into it
                        Mat mDrawableSubmat = new Mat(new Size(480.0, 480.0), mOriginalImageSubmat.type());
                        Imgproc.resize(mOriginalImageSubmat, mDrawableSubmat, mDrawableSubmat.size());

                        Mat mColourSourceSubmat = mDrawableSubmat.clone();
                        Mat mCannyOutput = mDrawableSubmat.clone();

                        double minLineLength = 300.0;

                        ColourMatrix matrix = new ColourMatrix();

                        matrix.setColourMatch(colourMatch);
                        matrix.setColourOrder(colourOrder);
                        matrix.setComparison(comparison);
                        matrix.setDisplayHotspots(displayHotspots);
                        matrix.setDisplayOutline(displayOutline);
                        matrix.setIntensity(intensity);
                        matrix.setMatrixType(matrixType);

                        String output = matrix.decode(mColourSourceSubmat, mCannyOutput, mDrawableSubmat, minLineLength);
                        Log.i(TAG, "DJH - decoded: " + output);
                    }

                    mCamera.startPreview();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };

        mCamera.takePicture(null, null, callback);
    }
4

1 回答 1

0

Thread.sleep 本身并不坏。您可以使用循环到 30 和thread.sleep(100). 然后,您一次只能暂停 0.1 秒,而 CPU 仍然不会达到峰值。

于 2013-04-10T04:31:49.540 回答