等待相机保存照片,什么比thread.sleep更好?

时间:2013-04-10 04:20:03

标签: camera thread-sleep start-activity

我有一个自定义的OpenCV相机活动,可以在点击屏幕时拍照。活动以startActivityForResult意图开始,活动结束后,照片的文件路径将返回到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);  
        }
    }

通知:顺便说一句,由于某些原因,requestCode每次都会以131074的形式返回,尽管startActivityForResult的设置为2,如果您知道,请告诉我为什么会这样。

最后,如果需要查看,请参阅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);
    }

1 个答案:

答案 0 :(得分:0)

Thread.sleep本身并不坏。您可以使用thread.sleep(100)的循环到30。然后你只会暂停.1秒,CPU仍然不会出现高峰。

相关问题