关于android自定义相机连续对焦功能的个人见解

这段时间项目中有个功能是像有道词典相机取词那样的一个工作,研究了好久,看不不少大神的代码,终于有了解决方案,思路是定义一个 Handler 来处理聚焦,每10毫秒聚焦一次,连续成功聚焦5次就执行拍照功能。我看到其他大神写的手机移动后就聚焦,功能很强大!我写的还有点缺陷,希望看到的大神能给完善下!谢谢!

我先定义了个SurfaceView:

package com.example.androidcamera;import java.io.IOException;import android.content.Context;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;/*** 相机基本预览类* @author wanglei**/
public class CameraView extends SurfaceView implements SurfaceHolder.Callback{private static final String TAG = "CameraView";private SurfaceHolder mySurfaceHolder;private Camera myCamera;
//	private PreviewCallback myPreviewCallback;//预览回调事件
//	private PictureCallback myPictureCallback;//拍照回调事件private AutoFocusCallback myAutoFocusCallback;/** 创建构造器 */@SuppressWarnings("deprecation")public CameraView(Context context,Camera camera,AutoFocusCallback autoFocusCallback) {super(context);myCamera =camera;
//		myPreviewCallback = previewCallback;
//		myPictureCallback = pictureCallback;myAutoFocusCallback = autoFocusCallback;mySurfaceHolder = getHolder();mySurfaceHolder.addCallback(this);mySurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);}@Override/*** 设置相机预览类*/public void surfaceCreated(SurfaceHolder holder) {try {Camera.Parameters parameters = myCamera.getParameters();
//			Log.i(TAG, "摄像头的各项参数:"+parameters.flatten());parameters.setPreviewSize(640, 480);//摄像头的像素parameters.setPictureSize(640, 480);//拍摄出照片的大小parameters.setPictureFormat(PixelFormat.JPEG);parameters.setJpegQuality(100);//jpg图片的质量parameters.setRotation(90);//相机旋转90度myCamera.setParameters(parameters);//把参数设回给摄像头myCamera.setPreviewDisplay(holder);} catch (IOException e) {Log.d(TAG, "相机预览类设置错误:"+e.getMessage());}}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stub}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {if(mySurfaceHolder.getSurface() == null) return;try {myCamera.startPreview();myCamera.setDisplayOrientation(90);myCamera.setPreviewDisplay(mySurfaceHolder);
//			myCamera.setPreviewCallback(myPreviewCallback);myCamera.startPreview();myCamera.autoFocus(myAutoFocusCallback);
//			myCamera.takePicture(null, null, myPictureCallback);} catch (Exception e) {Log.d(TAG, "相机开始预览错误"+e.getMessage());}}
}

接下来是相机类:定义了连续聚焦

package com.example.androidcamera;import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Handler;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;public class CameraActivity extends Activity{private static final String TAG = "CameraActivity";private Camera myCamera;private CameraView myCameraView;private Handler autoFocusHandler;private boolean previewing = true;private int takePictureType=0;private RelativeLayout layout;private ImageView imageView;private TextView textView;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_camera); //设置ViewStrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//设置屏幕方向autoFocusHandler = new Handler();myCamera = Camera.open();//打开相机myCameraView = new CameraView(this, myCamera,autoFocusCallback);FrameLayout frameLayout = (FrameLayout)this.findViewById(R.id.cameraPreview);frameLayout.addView(myCameraView);textView = (TextView)this.findViewById(R.id.textmsg);layout = (RelativeLayout)this.findViewById(R.id.returnMsg);imageView = (ImageView)this.findViewById(R.id.imageview);imageView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stublayout.setVisibility(ViewGroup.GONE);myCamera.startPreview();//开始预览previewing = true;myCamera.autoFocus(autoFocusCallback);}});}/**  关闭释放相机 */protected void onPause() {super.onPause();if(myCamera!=null){previewing = false;myCamera.setPreviewCallback(null);myCamera.release();myCamera = null;}};/** 拍照事件内部类  */PictureCallback pictureCallback = new PictureCallback() {@Overridepublic void onPictureTaken(byte[] data, Camera camera) {// TODO Auto-generated method stubLog.i(TAG, "执行:拍照事件内部类 ");layout.setVisibility(ViewGroup.VISIBLE);imageView.setImageBitmap(getBitmap(data));try {//保存裁剪好的图片File file = new File("mnt/sdcard/test.jpg");BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));getBitmap(data).compress(Bitmap.CompressFormat.JPEG, 80, bos);bos.flush();bos.close();} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}};/** 获取矩形区域内的截图 */private Bitmap getBitmap(byte[] data) {Bitmap bitmap =  BitmapFactory.decodeByteArray(data, 0, data.length);//获取图像
//		View myView = (View) this.findViewById(R.id.myView);int width = bitmap.getWidth();int height = bitmap.getHeight();Matrix m = new Matrix();m.setRotate(90,(float) width/2, (float) height/ 2);Bitmap testBitmap = Bitmap.createBitmap(bitmap, 0,0,width,height,m,true);//旋转图片Bitmap finalBitmap = Bitmap.createBitmap(testBitmap, testBitmap.getWidth()/20, testBitmap.getHeight()/20, testBitmap.getWidth()/20*19, testBitmap.getHeight()/20*2);//截取图片return finalBitmap;}/** 聚焦事件内部类 */AutoFocusCallback autoFocusCallback = new AutoFocusCallback() {@Overridepublic void onAutoFocus(boolean success, Camera camera) {//这里是连续聚焦算法if (success && takePictureType < 6) {takePictureType +=1;} else if (takePictureType > 5) {myCamera.takePicture(null, null, pictureCallback);previewing = false;takePictureType = 0;} else {takePictureType = 0;}autoFocusHandler.postDelayed(doAutoFocus, 10);// 每10毫秒连续聚焦Log.i(TAG, "success:" + success + " | takePictureType:"+ takePictureType);}};/** 聚焦线程 */private Runnable doAutoFocus = new Runnable() {@Overridepublic void run() {if(previewing){myCamera.autoFocus(autoFocusCallback);}}};
}

自定义view用于遮罩:

package com.example.androidcamera;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;public class MyView extends View {public MyView(Context context, AttributeSet attrs) {super(context, attrs);setLongClickable(true);this.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {//屏幕触摸事件待完成return false;}});}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);/*这里就是绘制矩形区域*/int width = this.getWidth();int height = this.getHeight();Paint paint = new Paint();paint.setColor(0xaa000000);canvas.drawRect(0, 0, width, height/20, paint);//topcanvas.drawRect(0, height/20, width/20, height/20*3, paint);//leftcanvas.drawRect(width/20*19, height/20, width , height/20*3, paint);//rightcanvas.drawRect(0, height/20*3, width, height, paint);//bottom}
}

xml布局:


系统清单文件:


代码就是这些了!希望有大神来帮忙完善下!谢谢。



本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部