我有一个自定义的 OpenCV 相机活动,可以在点击屏幕时拍照。Activity 是带着一个startActivityForResult
Intent 启动的,在 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);
}