Androi学习:Camera初探——控制摄像头拍照

转载自:http://blog.csdn.net/lissdy/article/details/8512395

实习接触的项目中需要调用系统摄像头进行拍照,通过完成这个功能点暂时初步了解了Android中的Camera,当然目前只是停留在使用阶段,对于Camera的深度剖析有机会也要了解一下。

通过Camera控制摄像头拍照的步骤:

1.调用Camera的open()方法打开相机。

2.调用Camera的setParameters()方法获取拍照参数。该方法返回一个Camera.Parameters对象。

3.调用Camera.Paramers对象方法设置拍照参数

4.调用Camera的setParameters,并将Camera.Paramers作为参数传入,这样即可对相机的拍照参数进行控制

5.调用Camera的startPreview()方法开始预览取景,在预览取景之前需要调用Camera的setPreViewDisplay(SurfaceHolder holder)方法设置使用哪个SurfaceView来显示取景图片。

6.调用Camera的takePicture()方法进行拍照.

7.结束程序时,调用Camera的StopPriview()结束取景预览,并调用release()方法释放资源。

运行效果:




涉及Camera使用的相关代码:

[java]  view plain  copy
  1. private void initCamera()  
  2.     {  
  3.         if (!isPreview)  
  4.         {  
  5.             camera = Camera.open();  //1.调用Camera的open()方法打开相机。  
  6.         }  
  7.         if (camera != null && !isPreview)  
  8.         {  
  9.             try  
  10.             {  
  11.                 //2.调用Camera的setParameters()方法获取拍照参数。该方法返回一个Camera.Parameters对象。  
  12.                 Camera.Parameters parameters = camera.getParameters();            
  13.                 //3.调用Camera.Paramers对象方法设置拍照参数  
  14.                 // 设置预览照片的大小  
  15.                 parameters.setPreviewSize(screenWidth, screenHeight);  
  16.                 // 每秒显示4帧  
  17.                 parameters.setPreviewFrameRate(4);  
  18.                 // 设置图片格式  
  19.                 parameters.setPictureFormat(PixelFormat.JPEG);  
  20.                 // 设置JPG照片的质量  
  21.                 parameters.set("jpeg-quality",85);  
  22.                 //设置照片的大小  
  23.                 parameters.setPictureSize(screenWidth, screenHeight);             
  24.                   
  25.                 //4.调用Camera的setParameters,并将Camera.Paramers作为参数传入,这样即可对相机的拍照参数进行控制  
  26.                 camera.setParameters(parameters);             
  27.                 /** 
  28.                  *  5.调用Camera的startPreview()方法开始预览取景,在预览取景之前需要调用 
  29.                  *  Camera的setPreViewDisplay(SurfaceHolder holder)方法设置使用哪个SurfaceView来显示取景图片。 
  30.                  *  通过SurfaceView显示取景画面 
  31.                  */           
  32.                 camera.setPreviewDisplay(surfaceHolder);  
  33.                 // 开始预览  
  34.                 camera.startPreview();  
  35.                 // 自动对焦  
  36.                 camera.autoFocus(afcb);  
  37.             }  
  38.             catch (Exception e)  
  39.             {  
  40.                 e.printStackTrace();  
  41.             }  
  42.             isPreview = true;  
  43.         }  
  44.     }  

[java]  view plain  copy
  1. //设置监听器,触摸屏幕即拍照  
  2. sView.setOnTouchListener(new View.OnTouchListener() {             
  3.     public boolean onTouch(View v, MotionEvent event) {  
  4.         // TODO Auto-generated method stub  
  5.         if(event.getAction()==MotionEvent.ACTION_DOWN){  
  6.             if (camera != null)  
  7.             {  
  8.                 // 6.调用Camera的takePicture()方法进行拍照.  
  9.                 camera.takePicture(nullnull , myjpegCallback);  
  10.                 return true;  
  11.             }  
  12.         }  
  13.         return false;  
  14.     }  
  15. });  

[plain]  view plain  copy
  1. // surface摧毁时释放摄像头  
  2.             public void surfaceDestroyed(SurfaceHolder holder)  
  3.             {  
  4.                 // 如果camera不为null ,释放摄像头  
  5.                 if (camera != null)  
  6.                 {  
  7.                     //7.结束程序时,调用Camera的StopPriview()结束取景预览,并调用release()方法释放资源.  
  8.                     if (isPreview)  
  9.                     camera.stopPreview();  
  10.                     camera.release();  
  11.                     camera = null;  
  12.                 }  
  13.             }     
完整代码:

[java]  view plain  copy
  1. public class TakephotoActivity extends Activity  
  2. {  
  3.     SurfaceView sView;  
  4.     SurfaceHolder surfaceHolder;  
  5.     int screenWidth, screenHeight;  
  6.     Button takePhoto;  
  7.     Camera camera;  // 定义系统所用的照相机  
  8.     boolean isPreview = false;//是否在浏览中  
  9.         @Override  
  10.     public void onCreate(Bundle savedInstanceState)  
  11.     {  
  12.         super.onCreate(savedInstanceState);  
  13.         // 设置全屏  
  14.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  15.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
  16.             WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  17.         //设置屏幕方向  
  18.         this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);  
  19.         setContentView(R.layout.takephoto);  
  20.           
  21.         takePhoto=(Button)findViewById(R.id.takephoto);  
  22.         takePhoto.setOnClickListener(new View.OnClickListener() {         
  23.             public void onClick(View v) {  
  24.                 if (camera != null)  
  25.                 {                   // 拍照  
  26.                     camera.takePicture(nullnull , myjpegCallback);  
  27.                 }  
  28.                   
  29.             }  
  30.         });  
  31.         WindowManager wm = (WindowManager) getSystemService(  
  32.             Context.WINDOW_SERVICE);  
  33.         Display display = wm.getDefaultDisplay();  
  34.         // 获取屏幕的宽和高  
  35.         screenWidth = display.getWidth();  
  36.         screenHeight = display.getHeight();  
  37.           
  38.         // 获取界面中SurfaceView组件  
  39.         sView = (SurfaceView) findViewById(R.id.sView);  
  40.         //设置监听器,触摸屏幕即拍照  
  41.         sView.setOnTouchListener(new View.OnTouchListener() {             
  42.             public boolean onTouch(View v, MotionEvent event) {  
  43.                 // TODO Auto-generated method stub  
  44.                 if(event.getAction()==MotionEvent.ACTION_DOWN){  
  45.                     if (camera != null)  
  46.                     {  
  47.                         // 6.调用Camera的takePicture()方法进行拍照.  
  48.                         camera.takePicture(nullnull , myjpegCallback);  
  49.                         return true;  
  50.                     }  
  51.                 }  
  52.                 return false;  
  53.             }  
  54.         });  
  55.         // 获得SurfaceView的SurfaceHolder  
  56.         surfaceHolder = sView.getHolder();  
  57.         // 为surfaceHolder添加一个回调监听器  
  58.         surfaceHolder.addCallback(new Callback()  
  59.         {  
  60.             public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  61.                 int height)  
  62.             {  
  63.             }  
  64.             public void surfaceCreated(SurfaceHolder holder)  
  65.             {  
  66.                 // surface被创建时打开摄像头  
  67.                 initCamera();  
  68.                   
  69.             }  
  70.             // surface摧毁时释放摄像头  
  71.             public void surfaceDestroyed(SurfaceHolder holder)  
  72.             {  
  73.                 // 如果camera不为null ,释放摄像头  
  74.                 if (camera != null)  
  75.                 {  
  76.                     //7.结束程序时,调用Camera的StopPriview()结束取景预览,并调用release()方法释放资源.  
  77.                     if (isPreview)  
  78.                     camera.stopPreview();  
  79.                     camera.release();  
  80.                     camera = null;  
  81.                 }  
  82.             }         
  83.         });  
  84.         // 设置该SurfaceView自己不维护缓冲      
  85.         surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
  86.     }  
  87.     private void initCamera()  
  88.     {  
  89.         if (!isPreview)  
  90.         {  
  91.             camera = Camera.open();  //1.调用Camera的open()方法打开相机。  
  92.         }  
  93.         if (camera != null && !isPreview)  
  94.         {  
  95.             try  
  96.             {  
  97.                 //2.调用Camera的setParameters()方法获取拍照参数。该方法返回一个Camera.Parameters对象。  
  98.                 Camera.Parameters parameters = camera.getParameters();            
  99.                 //3.调用Camera.Paramers对象方法设置拍照参数  
  100.                 // 设置预览照片的大小  
  101.                 parameters.setPreviewSize(screenWidth, screenHeight);  
  102.                 // 每秒显示4帧  
  103.                 parameters.setPreviewFrameRate(4);  
  104.                 // 设置图片格式  
  105.                 parameters.setPictureFormat(PixelFormat.JPEG);  
  106.                 // 设置JPG照片的质量  
  107.                 parameters.set("jpeg-quality",85);  
  108.                 //设置照片的大小  
  109.                 parameters.setPictureSize(screenWidth, screenHeight);             
  110.                   
  111.                 //4.调用Camera的setParameters,并将Camera.Paramers作为参数传入,这样即可对相机的拍照参数进行控制  
  112.                 camera.setParameters(parameters);             
  113.                 /** 
  114.                  *  5.调用Camera的startPreview()方法开始预览取景,在预览取景之前需要调用 
  115.                  *  Camera的setPreViewDisplay(SurfaceHolder holder)方法设置使用哪个SurfaceView来显示取景图片。 
  116.                  *  通过SurfaceView显示取景画面 
  117.                  */           
  118.                 camera.setPreviewDisplay(surfaceHolder);  
  119.                 // 开始预览  
  120.                 camera.startPreview();  
  121.                 // 自动对焦  
  122.                 camera.autoFocus(afcb);  
  123.             }  
  124.             catch (Exception e)  
  125.             {  
  126.                 e.printStackTrace();  
  127.             }  
  128.             isPreview = true;  
  129.         }  
  130.     }     
  131.       
  132.     AutoFocusCallback afcb=new AutoFocusCallback() {      
  133.         public void onAutoFocus(boolean success, Camera camera) {  
  134.             if(success){  
  135.                 //takePhoto.setEnabled(true);  
  136.                 System.out.println("可以拍照");  
  137.             }             
  138.         }  
  139.     };  
  140.       
  141.     PictureCallback myjpegCallback = new PictureCallback()  
  142.     {  
  143.         public void onPictureTaken(byte[] data, Camera camera)  
  144.         {  
  145.             // 根据拍照所得的数据创建位图  
  146.             final Bitmap bitmap = BitmapFactory.decodeByteArray(data  
  147.                 , 0, data.length);  
  148.             // 加载/layout/save.xml文件对应的布局资源  
  149.             View saveDialog = getLayoutInflater().inflate(  
  150.                 R.layout.save, null);  
  151.             final EditText photoName = (EditText) saveDialog  
  152.                 .findViewById(R.id.phone_name);  
  153.             // 获取saveDialog对话框上的ImageView组件  
  154.             ImageView show = (ImageView) saveDialog.findViewById(R.id.show);  
  155.             // 显示刚刚拍得的照片  
  156.             show.setImageBitmap(bitmap);  
  157.             //使用对话框显示saveDialog组件  
  158.             new AlertDialog.Builder(TakephotoActivity.this)  
  159.                 .setView(saveDialog)  
  160.                 .setPositiveButton("上传"new OnClickListener()  
  161.                 {  
  162.                     public void onClick(DialogInterface dialog,  
  163.                         int which)  
  164.                     {  
  165.                         // 创建一个位于SD卡上的文件  
  166.                         File file = new File(Environment.getExternalStorageDirectory()  
  167.                             ,  photoName.getText().toString() + ".jpg");  
  168.                         FileOutputStream outStream = null;  
  169.                         try  
  170.                         {  
  171.                             // 打开指定文件对应的输出流  
  172.                             outStream = new FileOutputStream(file);  
  173.                             // 把位图输出到指定文件中  
  174.                             Matrix matrix = new Matrix();  
  175.                             Bitmap bm = Bitmap.createBitmap(12001200*bitmap.getHeight()/bitmap.getWidth(), Config.ARGB_8888);//固定所拍相片大小  
  176.                             matrix.setScale(( float ) bm.getWidth() / ( float ) bitmap.getWidth(),( float ) bm.getHeight() / ( float ) bitmap.getHeight());// 注意参数一定是float哦  
  177.                             Canvas canvas = new Canvas(bm);//用bm创建一个画布 可以往bm中画入东西了  
  178.                             canvas.drawBitmap(bitmap,matrix,null);        
  179.                             bm.compress(CompressFormat.JPEG, 40, outStream);  
  180.                             outStream.close();  
  181.                         }  
  182.                         catch (IOException e)  
  183.                         {  
  184.                             e.printStackTrace();  
  185.                         }  
  186.                     }  
  187.                 })  
  188.                 .setNegativeButton("取消"null)  
  189.                 .show();  
  190.             //重新浏览  
  191.             camera.stopPreview();  
  192.             camera.startPreview();  
  193.             isPreview = true;  
  194.         }  
  195.     };  
  196. }  
网上看到Camera架构相关文章很对,有空也了解一下。 奋斗
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值