我一直在尝试使用Android中的Surface Preview使用相机拍照。 Surface Preview跨越布局中的整个屏幕。
每当我调用takePicture时,它都会失败并说我没有启用预览。
这里有活动变量,图片方法和摄像头拍照代码(它在onResume()中):
try {
Parent.class.getMethod("display").invoke(parent);
} catch(SecurityException | NoSuchMethodException | IllegalArgumentException | IllegalAccessException | InvocationTargetException | ex) {
// oops!
}
这就是错误:
public class FawkesRCActivity extends Activity implements SurfaceHolder.Callback {
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
public Camera mCamera;
...
Camera.PictureCallback camHolla = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
String photoFile = "F_Auton.jpg";
File sdDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String filename =sdDir + File.separator + photoFile;
File pictureFile = new File(filename);
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (Exception e) {
Log.d("Errored:", e.getMessage());
}
}
};
public void setCamera(Camera camera) {
if (mCamera == camera) { return; }
stopPreviewAndFreeCamera();
mCamera = camera;
if (mCamera != null) {
List<Camera.Size> localSizes = mCamera.getParameters().getSupportedPreviewSizes();
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
// Important: Call startPreview() to start updating the preview
// surface. Preview must be started before you can take a picture.
mCamera.startPreview();
}
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
mCamera.startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
// Call stopPreview() to stop updating the preview surface.
mCamera.stopPreview();
}
}
/**
* When this function returns, mCamera will be null.
*/
private void stopPreviewAndFreeCamera() {
if (mCamera != null) {
// Call stopPreview() to stop updating the preview surface.
mCamera.stopPreview();
// Important: Call release() to release the camera for use by other
// applications. Applications should release the camera immediately
// during onPause() and re-open() it during onResume()).
mCamera.release();
mCamera = null;
}
}
@Override
protected void onResume() {
FawkesRCActivity.this.runOnUiThread(new Runnable() {
public void run() {
mSurfaceView = (SurfaceView) findViewById(R.id.cameraPreview);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(FawkesRCActivity.this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
int camId=0;
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
camId=i;
}
}
if (safeCameraOpen(camId))Log.e("Camera","All Good"); else Log.e("Camera","Errored");
try{
SurfaceTexture surfaceTexture = new SurfaceTexture(0);
mCamera.setPreviewTexture(surfaceTexture);
// mCamera.startPreview();
}
catch(Exception e){
e.printStackTrace();
}
try {
mCamera.takePicture(null, null, null, camHolla);
}
catch(Exception e){
e.printStackTrace();
}
}
});
super.onResume();
}
private boolean safeCameraOpen(int id) {
boolean qOpened = false;
try {
releaseCameraAndPreview();
mCamera = Camera.open(id);
qOpened = (mCamera != null);
} catch (Exception e) {
Log.e(getString(R.string.app_name), "failed to open Camera");
e.printStackTrace();
}
return qOpened;
}
private void releaseCameraAndPreview() {
setCamera(null);
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
}
在搜索论坛几个小时后,我完全迷失了,任何帮助都会受到赞赏。
答案 0 :(得分:0)
我不是专家,但我认为你在拍照之前没有给mCamera.startPreview()
打电话。您可以尝试在此之前调用它。
您可以查看此CameraFragment Sample作为启动相机预览的参考,依此类推。
答案 1 :(得分:0)
摄像机操作不是即时的,通常不是同步的。一些设备在startPreview()和takePicture()之间需要很长的延迟,例如在OnePlus One上你需要至少100毫秒。
对代码的最小修复可能是
try{
SurfaceTexture surfaceTexture = new SurfaceTexture(0);
mCamera.setPreviewTexture(surfaceTexture);
// mCamera.startPreview();
}
catch(Exception e){
e.printStackTrace();
}
mSurfaceView.postDelayed(new Runnable() {
@Override
public void run() {
try {
mCamera.takePicture(null, null, null, camHolla);
}
catch(Exception e){
e.printStackTrace();
}
}, 100);
super.onResume();