实现自己的Camera

http://blog.csdn.net/chenjie19891104/archive/2011/04/13/6321066.aspx

Android自带的Camera应用虽然可以满足大多数情景,但是其灵活性上还有不足。但是Android允许我们定制自己的Camera。

在Android的hardware包中有一个Camera类。这个类就是获取Camera服务的,可以定制Camera等。

可以通过open()方法获取其实例。

在使用这个类是需要在AndroidManifest.xml文件中加入相应的权限和特性

如:

  <uses-permission android:name = "android.permission.CAMERA" />
 
<uses-feature android:name = "android.hardware.camera" />
 
<uses-feature android:name = "android.hardware.camera.autofocus" />


等。

本文实例:

Copy to clipboard
  1. package demo.camera;    
  2. import java.io.OutputStream;    
  3. import java.util.Iterator;    
  4. import java.util.List;    
  5. import android.app.Activity;    
  6. import android.content.ContentValues;    
  7. import android.content.res.Configuration;    
  8. import android.hardware.Camera;    
  9. import android.net.Uri;    
  10. import android.os.Bundle;    
  11. import android.provider.MediaStore;    
  12. import android.view.SurfaceHolder;    
  13. import android.view.SurfaceView;    
  14. import android.view.View;    
  15. import android.widget.LinearLayout;    
  16. /**  
  17.  * Android自带的Camera应用程序可以完成很多功能。但是当其不能满足我们需要的时候  
  18.  * 我们可以定制自己的Camera。Android提供了Camera类来辅助我们实现自己的Camera。  
  19.  * 这个例子就来定义一个自己的Camera  
  20.  * 首先,在Manifest中需要引入权限<uses-permission android:name="android:permission.CAMERA"/>  
  21.  * 我们需要用来存放取景器的容器,这个容器就是SurfaceView。  
  22.  * 使用SurfaceView的同时,我们还需要使用到SurfaceHolder,SurfaceHolder相当于一个监听器,可以监听  
  23.  * Surface上的变化,通过其内部类CallBack来实现。  
  24.  * 为了可以获取图片,我们需要使用Camera的takePicture方法同时我们需要实现Camera.PictureCallBack类,实现onPictureTaken方法  
  25.  * @author Administrator  
  26.  *  
  27.  */    
  28. public class MyCamera extends Activity implements SurfaceHolder.Callback,Camera.PictureCallback{    
  29.         
  30.     public static final int MAX_WIDTH = 200;    
  31.     public static final int MAX_HEIGHT = 200;    
  32.         
  33.     private SurfaceView surfaceView;    
  34.         
  35.     private Camera camera; //这个是hardare的Camera对象    
  36.         
  37.     public void onCreate(Bundle savedInstanceState){    
  38.         super.onCreate(savedInstanceState);    
  39.         this.setContentView(R.layout.camera);    
  40.         surfaceView = (SurfaceView)this.findViewById(R.id.myCameraView);    
  41.         surfaceView.setFocusable(true);     
  42.         surfaceView.setFocusableInTouchMode(true);    
  43.         surfaceView.setClickable(true);    
  44.         surfaceView.setOnClickListener(new View.OnClickListener() {    
  45.                 
  46.             @Override    
  47.             public void onClick(View v) {    
  48.                     
  49.                 camera.takePicture(nullnullnull, MyCamera.this);    
  50.                     
  51.             }    
  52.         });    
  53.         //SurfaceView中的getHolder方法可以获取到一个SurfaceHolder实例    
  54.         SurfaceHolder holder = surfaceView.getHolder();    
  55.         //为了实现照片预览功能,需要将SurfaceHolder的类型设置为PUSH    
  56.         //这样,画图缓存就由Camera类来管理,画图缓存是独立于Surface的    
  57.         holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);    
  58.         holder.addCallback(this);    
  59.     }    
  60.     @Override    
  61.     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {    
  62.     }    
  63.     @Override    
  64.     public void surfaceCreated(SurfaceHolder holder) {    
  65.         // 当Surface被创建的时候,该方法被调用,可以在这里实例化Camera对象    
  66.         //同时可以对Camera进行定制    
  67.         camera = Camera.open(); //获取Camera实例    
  68.         
  69.             
  70.         /**  
  71.          * Camera对象中含有一个内部类Camera.Parameters.该类可以对Camera的特性进行定制  
  72.          * 在Parameters中设置完成后,需要调用Camera.setParameters()方法,相应的设置才会生效  
  73.          * 由于不同的设备,Camera的特性是不同的,所以在设置时,需要首先判断设备对应的特性,再加以设置  
  74.          * 比如在调用setEffects之前最好先调用getSupportedColorEffects。如果设备不支持颜色特性,那么该方法将  
  75.          * 返回一个null  
  76.          */    
  77.         try {    
  78.                 
  79.             Camera.Parameters param = camera.getParameters();    
  80.             if(this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){    
  81.                 //如果是竖屏    
  82.                 param.set("orientation""portrait");    
  83.                 //在2.2以上可以使用    
  84.                 //camera.setDisplayOrientation(90);    
  85.             }else{    
  86.                 param.set("orientation""landscape");    
  87.                 //在2.2以上可以使用    
  88.                 //camera.setDisplayOrientation(0);                  
  89.             }    
  90.             //首先获取系统设备支持的所有颜色特效,有复合我们的,则设置;否则不设置    
  91.             List<String> colorEffects = param.getSupportedColorEffects();    
  92.             Iterator<String> colorItor = colorEffects.iterator();    
  93.             while(colorItor.hasNext()){    
  94.                 String currColor = colorItor.next();    
  95.                 if(currColor.equals(Camera.Parameters.EFFECT_SOLARIZE)){    
  96.                     param.setColorEffect(Camera.Parameters.EFFECT_SOLARIZE);    
  97.                     break;    
  98.                 }    
  99.             }    
  100.             //设置完成需要再次调用setParameter方法才能生效    
  101.             camera.setParameters(param);    
  102.                 
  103.             camera.setPreviewDisplay(holder);    
  104.                 
  105.             /**  
  106.              * 在显示了预览后,我们有时候希望限制预览的Size  
  107.              * 我们并不是自己指定一个SIze而是指定一个Size,然后  
  108.              * 获取系统支持的SIZE,然后选择一个比指定SIZE小且最接近所指定SIZE的一个  
  109.              * Camera.Size对象就是该SIZE。  
  110.              *   
  111.              */    
  112.             int bestWidth = 0;    
  113.             int bestHeight = 0;    
  114.                 
  115.             List<Camera.Size> sizeList = param.getSupportedPreviewSizes();    
  116.             //如果sizeList只有一个我们也没有必要做什么了,因为就他一个别无选择    
  117.             if(sizeList.size() > 1){    
  118.                 Iterator<Camera.Size> itor = sizeList.iterator();    
  119.                 while(itor.hasNext()){    
  120.                     Camera.Size cur = itor.next();    
  121.                     if(cur.width > bestWidth && cur.height>bestHeight && cur.width <MAX_WIDTH && cur.height < MAX_HEIGHT){    
  122.                         bestWidth = cur.width;    
  123.                         bestHeight = cur.height;    
  124.                     }    
  125.                 }    
  126.                 if(bestWidth != 0 && bestHeight != 0){    
  127.                     param.setPreviewSize(bestWidth, bestHeight);    
  128.                     //这里改变了SIze后,我们还要告诉SurfaceView,否则,Surface将不会改变大小,进入Camera的图像将质量很差    
  129.                     surfaceView.setLayoutParams(new LinearLayout.LayoutParams(bestWidth, bestHeight));    
  130.                 }    
  131.             }    
  132.             camera.setParameters(param);    
  133.         } catch (Exception e) {    
  134.             // 如果出现异常,则释放Camera对象    
  135.             camera.release();    
  136.         }    
  137.             
  138.         //启动预览功能    
  139.         camera.startPreview();    
  140.             
  141.     }    
  142.     @Override    
  143.     public void surfaceDestroyed(SurfaceHolder holder) {    
  144.         // 当Surface被销毁的时候,该方法被调用    
  145.         //在这里需要释放Camera资源    
  146.         camera.stopPreview();    
  147.         camera.release();    
  148.             
  149.     }    
  150.     @Override    
  151.     public void onPictureTaken(byte[] data, Camera camera) {    
  152.         // data是一个原始的JPEG图像数据,    
  153.         //在这里我们可以存储图片,很显然可以采用MediaStore    
  154.         //注意保存图片后,再次调用startPreview()回到预览    
  155.         Uri imageUri = this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());    
  156.         try {    
  157.             OutputStream os = this.getContentResolver().openOutputStream(imageUri);    
  158.             os.write(data);    
  159.             os.flush();    
  160.             os.close();    
  161.         } catch (Exception e) {    
  162.             // TODO: handle exception    
  163.             e.printStackTrace();    
  164.         }    
  165.             
  166.         camera.startPreview();    
  167.     }    
  168.         
  169.         
  170.         
  171. }   

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值