当前位置:   article > 正文

6、纯java调用摄像头预览小记1--Camera1_java调用手机摄像头

java调用手机摄像头

前言:本片记录下纯Java下打开摄像头预览,介绍下Camera1的使用方法。

工程:andriod 4,Camera1

安卓调用摄像头有两种方案,一种是调用intent方法使用摄像头(直接调用系统),另一种是通过camera类使用摄像头(自己写),笔者这里使用第二种方案。

本来想把camera1和camera2的使用都放在一篇文章中写,后来发现审核不过,所以就分两篇介绍了。

一、新建工程

二、权限设置

AndroidManifest.xml设置CAMERA权限,不设置权限的话,会闪退或者报错,这里是安卓4.0,不需要去动态权限申请,5.0后需要。

三、界面设置

.xml中添加

有个红线,下面文章中说了原因,不用管暂时This view is not constrained. It only has designtime positions, so it will jump to (0,0) ..._哒哒呵的博客-CSDN博客

四、Camera1 

4.1 Camera类的相关方法

Camera.open(); 打开设备摄像头,并返回一个Camera对象。可以通过返回的对象管理摄像头。

Camera.setPreviewDisplay(SurfaceHolder holder); 设置显示摄像头内容的surfaceView,参数为显示surfaceVIew所对应的surfaceHolder。

Camera.startPreview();  开始预览摄像头。即在surfaceView上显示摄像头拍摄信息。

Camera.stopPreview();  关闭摄像头。

Camera.release(); 放开摄像头。

4.2 SurfaceView类的相关方法

SurfaceView.getHolder(); 获得surfaceHolder对象,surfaceHolder能够对surfaceView进行控制,且能够添加回调函数来监控surfaceView的变化,同时我们也需要获得surfaceHolder来作为Camera.setPreviewDisplay();方法的参数。

public abstract void addCallback (SurfaceHolder.Callback callback) ; 为surfaceHolder添加回调方法,我们可以直接在使用方法的时候new 一个callback或者实现callback的接口SurfaceHolder.Callback;

public abstract void setType (int type); 在早期的安卓中,我们需要这个方法来设置surfaceView的类型,一般值设置为SURFACE_TYPE_PUSH_BUFFERS; 但是在API 11中该方法已经过时,系统会默认为其设置值。这点还需要再实际开发中再进行验证。

SurfaceHolder的三个回调函数

  1. public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) ;
  2. public void surfaceCreated(SurfaceHolder arg0) ;
  3. public void surfaceDestroyed(SurfaceHolder arg0);

 4.3 使用

  1. private SurfaceView surfaceview;
  2. private SurfaceHolder holder;
  3. private Camera mCamera;
  4. private Camera.Size size;
  5. private int facingBack = Camera.CameraInfo.CAMERA_FACING_BACK;
  6. private Camera.CameraInfo mFrontCameraInfo = null;
  7. private Camera.CameraInfo mBackCameraInfo = null;
  8. private int mFrontCameraId = -1;
  9. private int mBackCameraId = -1;
  10. @Override
  11. protected void onCreate(Bundle savedInstanceState) {
  12. super.onCreate(savedInstanceState);
  13. setContentView(R.layout.activity_main);
  14. surfaceview=findViewById(R.id.surfaceView);
  15. holder= surfaceview.getHolder();
  16. holder.addCallback(new SurfaceHolder.Callback() {
  17. @Override
  18. public void surfaceCreated(SurfaceHolder surfaceHolder) {
  19. int numberOfCameras = Camera.getNumberOfCameras();
  20. for (int cameraId = 0; cameraId < numberOfCameras ; cameraId++){
  21. Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
  22. Camera.getCameraInfo(cameraId, cameraInfo);
  23. if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
  24. // 后置摄像头信息
  25. mBackCameraId = cameraId;
  26. mBackCameraInfo = cameraInfo;
  27. } else if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT){
  28. // 前置摄像头信息
  29. mFrontCameraId = cameraId;
  30. mFrontCameraInfo = cameraInfo;
  31. }
  32. }
  33. if(mCamera==null){
  34. //mCamera.setDisplayOrientation(90);
  35. mCamera=Camera.open();
  36. }
  37. try {
  38. //setCameraParameters();设置camera参数
  39. //默认情况下camera在surfaceview中的方向与正常方向差了90度,
  40. // 所以需要使用Camera.setDisplayOrientation(90);来调整。
  41. //还必须在这里设置,其他地方会闪退,
  42. mCamera.setDisplayOrientation(90);
  43. mCamera.setPreviewDisplay(holder);
  44. mCamera.startPreview();//开始预览
  45. } catch (IOException e){
  46. e.printStackTrace();
  47. Toast.makeText(MainActivity.this, "打开相机失败", Toast.LENGTH_SHORT).show();
  48. }
  49. }
  50. @Override
  51. public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
  52. }
  53. @Override
  54. public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
  55. }
  56. });
  57. }

上面代码中将下面设置camera代码注释掉了,只是在开启预览前调整了下显示方向,如果调用这个函数,就不用调显示方向了,因为这里面都设置好了。 

  1. private void setCameraParameters() {
  2. if (mCamera == null) {
  3. return;
  4. }
  5. Camera.Parameters parameters = mCamera.getParameters();
  6. mCamera.setDisplayOrientation(90);//220214 komla 摄像机的预览角度
  7. //增加对聚焦模式的判断,没有它会很模糊
  8. List<String> focusModesList = parameters.getSupportedFocusModes();
  9. if (focusModesList.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
  10. parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
  11. } else if (focusModesList.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
  12. parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
  13. }
  14. parameters.setRecordingHint(true);
  15. mCamera.setParameters(parameters);
  16. mCamera.getParameters().getSupportedVideoSizes();
  17. if (size == null) {
  18. //所有支持的宽高的集合
  19. List<Camera.Size> mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
  20. //从小到大排序
  21. Collections.sort(mSupportedPreviewSizes, (o1, o2) -> Integer.compare(o1.width, o2.width));
  22. //因为尺寸太大也不好,容量也就太大,所以只要满足要求就行,要求是宽大于1000或者高大于800的最小的一个
  23. for (int num = 0; num < mSupportedPreviewSizes.size(); num++) {
  24. Camera.Size size1 = mSupportedPreviewSizes.get(num);
  25. if (size1.width >= 1000 && size1.height >= 800) {
  26. size = size1;
  27. break;
  28. }
  29. }
  30. }
  31. parameters.setPreviewSize(640, 480);
  32. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/102865
推荐阅读
相关标签
  

闽ICP备14008679号