到目前为止我做了什么:
我已经实现了自定义相机来读取qr代码,需要继续对焦相机以便更好地阅读。
我的问题是当我使用处理程序时,相机闪光灯开关\关闭按钮不起作用或者打开和关闭相机闪光灯需要太多时间。当我每秒移除自动聚焦相机的代码(可运行和处理程序)时,每件事情都能正常工作。
我希望能够在相机移动时自动快速对焦,并且无需使用Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE
即可快速按需开启和关闭闪光灯,因为它不适用于{{1 }}
我曾经使用过API<14
,但它只启动了一次相机,这就是为什么我每天使用处理程序对焦相机。
Min SDK 项目版本为9。
我的相机活动
Camera.Parameters.FOCUS_MODE_AUTO
Camera Preview类是:
public class CameraActivityNew extends Activity implements OnClickListener,
Camera.PreviewCallback {
CameraPreviewNew mPreview;
FrameLayout flCameraPreview;
ImageButton ibFlashButton;
Boolean isFlashOn = false;
Camera mCamera;
private Handler mAutoFocusHandler;
private boolean mPreviewing = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
mAutoFocusHandler = new Handler();
setContentView(R.layout.activity_camera);
findSetupViews();
mPreview = new CameraPreviewNew(getApplicationContext(), this,
autoFocusCB);
flCameraPreview.addView(mPreview);
}
private Runnable doAutoFocus = new Runnable() {
public void run() {
if (mCamera != null && mPreviewing) {
mCamera.autoFocus(autoFocusCB);
}
}
};
Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
}
};
@Override
protected void onResume() {
super.onResume();
try {
mCamera = Camera.open();
if (mCamera == null) {
return;
}
} catch (Exception e) {
e.printStackTrace();
return;
}
mPreview.setCamera(mCamera);
mPreview.showSurfaceView();
mPreviewing = true;
}
@Override
protected void onPause() {
super.onPause();
if (mCamera != null) {
mPreview.setCamera(null);
mCamera.cancelAutoFocus();
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
mPreview.hideSurfaceView();
mPreviewing = false;
mCamera = null;
}
}
private void findSetupViews() {
flCameraPreview = (FrameLayout) findViewById(R.id.flCameraPreview);
ibFlashButton = (ImageButton) findViewById(R.id.ibFlash);
ibFlashButton.setOnClickListener(this);
if (getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA_FLASH)) {
ibFlashButton.setVisibility(View.VISIBLE);
ibFlashButton.setOnClickListener(this);
} else {
ibFlashButton.setVisibility(View.GONE);
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.ibFlash:
if (isFlashOn) {
mPreview.setCameraFlashLight(false);
isFlashOn = false;
ibFlashButton.setImageResource(R.drawable.flashoff);
} else {
mPreview.setCameraFlashLight(true);
ibFlashButton.setImageResource(R.drawable.flashon);
isFlashOn = true;
}
break;
}
}
@Override
public void onPreviewFrame(final byte[] data, final Camera camera) {
// processed here qr code and works fine if camera focus
//now removed to narrow the code for posting the question
}
}
答案 0 :(得分:5)
我发现您的自动对焦处理代码存在一些问题 分析结果
自动对焦中有循环。
<强>解释强>
a)相机预览类
mAutoFocusCallback
设置为相机活动的autoFocusCb
。
public CameraPreviewNew(Context context,...,AutoFocusCallback autoFocusCb)
{
super(context);
mAutoFocusCallback = autoFocusCb;
...
}
b) surfaceChanged 在加载活动时被调用一次。要求相机进行自动对焦。
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
{
if (mCamera != null)
{
...
mCamera.startPreview();
/*Auto focus camera and call <code>mAutoFocusCallback</code> after autofocus.*/
mCamera.autoFocus(mAutoFocusCallback);
...
}
}
c)完成自动对焦后,将调用
mAutoFocusCallback
回调。mAutoFocusCallback->autoFocusCb->onAutoFocus()
相机活动
Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
}
};
d)
onAutoFocus
在1000毫秒,1秒后再安排一次自动聚焦 相机活动
public void onAutoFocus(boolean success, Camera camera) {
mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
}
e)一秒钟后,消息将传递给处理程序,该处理程序将可运行的
doAutoFocus
请求摄像头调用为自动对焦,类似于上面的b。
private Runnable doAutoFocus = new Runnable() {
public void run() {
if (mCamera != null && mPreviewing) {
mCamera.autoFocus(autoFocusCB);
}
}
};
f)完成autoFocus后,再次调用
autoFocusCB
,类似于c)。并继续循环。
Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
}
};
解决方案
我很困惑为什么会这样实施。循环可能是没有收听闪存启用/禁用呼叫的原因。你需要删除下面的代码并做一些有意义的事情,否则将onAutoFocus()留空。
Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
/*REMOVE LINE BELOW*/
mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
}
};
每次相机移动时进行自动对焦,您需要借助手机附带的运动传感器。你可以谷歌吗
希望有所帮助。
快乐的编码...
答案 1 :(得分:4)
您似乎不需要为您的应用使用AutoFocusCallBack
,因为除了delay 1 second
之外您什么也没做。
您可以做的一直关注的是使用FOCUS_MODE_CONTINUOUS_PICTURE
(阅读更多here),setFocus
方法位于CameraPreview
,而不是{{1} }}):
Activity
并在public void setFocus() {
Camera.Parameters p = mCamera.getParameters();
p.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
mCamera.setParameters(p);
mCamera.startPreview();
}
中调用它:
SurfaceChanged
对于public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = mCamera.getParameters();
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
// You need to choose the most appropriate previewSize for your app
Camera.Size previewSize = previewSizes.get(0);
parameters.setPreviewSize(previewSize.width, previewSize.height);
parameters.setRotation(90);
mCamera.setParameters(parameters);
mCamera.startPreview();
setFlash(true);
setZoomLevel(5);
setFocus();
Log.w(TAG, "surfaceChanged()");
}
,您可以使用flash
中的此方法:
CameraPreview
希望它对你有所帮助!如果您对我的回答有任何疑问,请随时发表评论。
答案 2 :(得分:0)
虽然这一定要迟到,但如果要切换摄像机参数,最好按以下步骤操作
mCamera.stopPreview();
mCamera.setParameters(params); // set flash on in Camera parameters
mCamera.startPreview();