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" />
等。

本文实例:

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

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. Python list sort方法的具体使用
  3. python list.sort()根据多个关键字排序的方法实现
  4. android上一些方法的区别和用法的注意事项
  5. android实现字体闪烁动画的方法
  6. Android(安卓)Wifi模块分析(三)
  7. Android中dispatchDraw分析
  8. 使用NetBeans搭建Android开发环境
  9. Android四大基本组件介绍与生命周期

随机推荐

  1. Android的线程使用来更新UI----Thread、H
  2. Android(安卓)TTS学习--使用中文语音
  3. Android笔试的一部分知识点
  4. Relativelayout
  5. Android(安卓)开发入门问题集:启动模拟器
  6. Android之子线程更新UI
  7. android GridView item中组件获取焦点
  8. android服务学习service之AIDL
  9. 第六章(3) Android中的Drawable
  10. Android(安卓)混淆代码问题总结