Android开发:Camera初探——控制摄像头拍照

本文详细介绍了一个基于Android平台的拍照功能实现过程,包括全屏设置、屏幕方向调整、使用SurfaceView预览摄像头画面、触摸拍照、自动对焦及图片保存等功能。

http://www.linuxidc.com/Linux/2013-01/78025p2.htm

完整代码:

public class TakephotoActivity extends Activity
{
 SurfaceView sView;
 SurfaceHolder surfaceHolder;
 int screenWidth, screenHeight;
 Button takePhoto;
 Camera camera;  // 定义系统所用的照相机
 boolean isPreview = false;//是否在浏览中
        @Override
 public void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  // 设置全屏
  requestWindowFeature(Window.FEATURE_NO_TITLE);
  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
   WindowManager.LayoutParams.FLAG_FULLSCREEN);
  //设置屏幕方向
  this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
  setContentView(R.layout.takephoto);
 
  takePhoto=(Button)findViewById(R.id.takephoto);
  takePhoto.setOnClickListener(new View.OnClickListener() { 
   public void onClick(View v) {
    if (camera != null)
    {     // 拍照
     camera.takePicture(null, null , myjpegCallback);
    }
   
   }
  });
  WindowManager wm = (WindowManager) getSystemService(
   Context.WINDOW_SERVICE);
  Display display = wm.getDefaultDisplay();
  // 获取屏幕的宽和高
  screenWidth = display.getWidth();
  screenHeight = display.getHeight();
 
  // 获取界面中SurfaceView组件
  sView = (SurfaceView) findViewById(R.id.sView);
  //设置监听器,触摸屏幕即拍照
  sView.setOnTouchListener(new View.OnTouchListener() {   
   public boolean onTouch(View v, MotionEvent event) {
    // TODO Auto-generated method stub
    if(event.getAction()==MotionEvent.ACTION_DOWN){
     if (camera != null)
     {
      // 6.调用Camera的takePicture()方法进行拍照.
      camera.takePicture(null, null , myjpegCallback);
      return true;
     }
    }
    return false;
   }
  });
  // 获得SurfaceView的SurfaceHolder
  surfaceHolder = sView.getHolder();
  // 为surfaceHolder添加一个回调监听器
  surfaceHolder.addCallback(new Callback()
  {
   public void surfaceChanged(SurfaceHolder holder, int format, int width,
    int height)
   {
   }
   public void surfaceCreated(SurfaceHolder holder)
   {
    // surface被创建时打开摄像头
    initCamera();
   
   }
   // surface摧毁时释放摄像头
   public void surfaceDestroyed(SurfaceHolder holder)
   {
    // 如果camera不为null ,释放摄像头
    if (camera != null)
    {
     //7.结束程序时,调用Camera的StopPriview()结束取景预览,并调用release()方法释放资源.
     if (isPreview)
     camera.stopPreview();
     camera.release();
     camera = null;
    }
   } 
  });
  // 设置该SurfaceView自己不维护缓冲   
  surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
 }
 private void initCamera()
 {
  if (!isPreview)
  {
   camera = Camera.open();  //1.调用Camera的open()方法打开相机。
  }
  if (camera != null && !isPreview)
  {
   try
   {
    //2.调用Camera的setParameters()方法获取拍照参数。该方法返回一个Camera.Parameters对象。
    Camera.Parameters parameters = camera.getParameters();   
    //3.调用Camera.Paramers对象方法设置拍照参数
    // 设置预览照片的大小
    parameters.setPreviewSize(screenWidth, screenHeight);
    // 每秒显示4帧
    parameters.setPreviewFrameRate(4);
    // 设置图片格式
    parameters.setPictureFormat(PixelFormat.JPEG);
    // 设置JPG照片的质量
    parameters.set("jpeg-quality",85);
    //设置照片的大小
    parameters.setPictureSize(screenWidth, screenHeight);   
   
    //4.调用Camera的setParameters,并将Camera.Paramers作为参数传入,这样即可对相机的拍照参数进行控制
    camera.setParameters(parameters);   
    /**
    *  5.调用Camera的startPreview()方法开始预览取景,在预览取景之前需要调用
    *  Camera的setPreViewDisplay(SurfaceHolder holder)方法设置使用哪个SurfaceView来显示取景图片。
    *  通过SurfaceView显示取景画面
    */   
    camera.setPreviewDisplay(surfaceHolder);
    // 开始预览
    camera.startPreview();
    // 自动对焦
    camera.autoFocus(afcb);
   }
   catch (Exception e)
   {
    e.printStackTrace();
   }
   isPreview = true;
  }
 } 
 
 AutoFocusCallback afcb=new AutoFocusCallback() { 
  public void onAutoFocus(boolean success, Camera camera) {
   if(success){
    //takePhoto.setEnabled(true);
    System.out.println("可以拍照");
   }   
  }
 };
 
 PictureCallback myjpegCallback = new PictureCallback()
 {
  public void onPictureTaken(byte[] data, Camera camera)
  {
   // 根据拍照所得的数据创建位图
   final Bitmap bitmap = BitmapFactory.decodeByteArray(data
    , 0, data.length);
   // 加载/layout/save.xml文件对应的布局资源
   View saveDialog = getLayoutInflater().inflate(
    R.layout.save, null);
   final EditText photoName = (EditText) saveDialog
    .findViewById(R.id.phone_name);
   // 获取saveDialog对话框上的ImageView组件
   ImageView show = (ImageView) saveDialog.findViewById(R.id.show);
   // 显示刚刚拍得的照片
   show.setImageBitmap(bitmap);
   //使用对话框显示saveDialog组件
   new AlertDialog.Builder(TakephotoActivity.this)
    .setView(saveDialog)
    .setPositiveButton("上传", new OnClickListener()
    {
     public void onClick(DialogInterface dialog,
      int which)
     {
      // 创建一个位于SD卡上的文件
      File file = new File(Environment.getExternalStorageDirectory()
       ,  photoName.getText().toString() + ".jpg");
      FileOutputStream outStream = null;
      try
      {
       // 打开指定文件对应的输出流
       outStream = new FileOutputStream(file);
       // 把位图输出到指定文件中
          Matrix matrix = new Matrix();
       Bitmap bm = Bitmap.createBitmap(1200, 1200*bitmap.getHeight()/bitmap.getWidth(), Config.ARGB_8888);//固定所拍相片大小
       matrix.setScale(( float ) bm.getWidth() / ( float ) bitmap.getWidth(),( float ) bm.getHeight() / ( float ) bitmap.getHeight());// 注意参数一定是float哦
       Canvas canvas = new Canvas(bm);//用bm创建一个画布 可以往bm中画入东西了
       canvas.drawBitmap(bitmap,matrix,null); 
       bm.compress(CompressFormat.JPEG, 40, outStream);
       outStream.close();
      }
      catch (IOException e)
      {
       e.printStackTrace();
      }
     }
    })
    .setNegativeButton("取消", null)
    .show();
   //重新浏览
   camera.stopPreview();
   camera.startPreview();
   isPreview = true;
  }
 };
}

网上看到Camera架构相关文章很对,有空也了解一下。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值