• 切换相机
    /
    void switchCamera(int facing);
    /
    *
  • 设置Facing
    /
    void setCameraFacing(int facing);
    /
    *
  • 获取Facing
    /
    int getCameraFacing();
    /
    *
  • 设置预览尺寸
    /
    void setPreviewSize(Size cameraSize);
    /
    *
  • 获取预览尺寸
    /
    Size getPreviewSize();
    /
    *
  • 设置显示旋转角度
    /
    void setDisplayOrientation(int displayOrientation);
    /
    *
  • 获取显示旋转角度
    /
    int getDisplayOrientation();
    /
    *
  • 释放相机
    /
    void releaseCamera();
    /
    *
  • 添加相机回调
    /
    void addOnCameraListener(OnCameraListener onCameraListener);
    /
    *
  • 移除相机回调
    /
    void removeOnCameraListener(OnCameraListener onCameraListener);
    /
    *
  • 移除所有回调
    */
    void removeAllOnCameraListener();
    }

注意到,里面有个相机回调OnCameraListener,这是自定义的一个相机回调

public interface OnCameraListener {
/**

  • 相机打开
    */
    void onCameraOpened(Size cameraSize, int facing);

/**

  • 相机关闭
    */
    void onCameraClosed();

/**

  • 相机异常
    */
    void onCameraError(Exception e);
    }

接下来,我们新建CameraManager,实现ICamera接口

public class CameraManager i 《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》无偿开源 徽信搜索公众号【编程进阶路】 mplements ICamera {
/**

  • Camera实现
    */
    private final ICamera camera = new Camera1();

/**

  • 后台线程
    */
    private Handler handler;
    private HandlerThread thread;

@Override
public void openCamera(Activity activity, SurfaceTexture surfaceTexture) {
postTask(new Runnable() {
@Override
public void run() {
camera.openCamera(activity, surfaceTexture);
}
});
}

@Override
public void openCamera(int facing, Activity activity, SurfaceTexture surfaceTexture) {
postTask(new Runnable() {
@Override
public void run() {
camera.openCamera(facing, activity, surfaceTexture);
}
});
}

@Override
public void closeCamera() {
postTask(new Runnable() {
@Override
public void run() {
camera.closeCamera();
}
});
}

@Override
public void switchCamera() {
postTask(new Runnable() {
@Override
public void run() {
camera.switchCamera();
}
});
}

@Override
public void switchCamera(int facing) {
postTask(new Runnable() {
@Override
public void run() {
camera.switchCamera(facing);
}
});
}

@Override
public void setCameraFacing(int facing) {
postTask(new Runnable() {
@Override
public void run() {
camera.setCameraFacing(facing);
}
});
}

@Override
public int getCameraFacing() {
return camera.getCameraFacing();
}

@Override
public void setPreviewSize(Size cameraSize) {
postTask(new Runnable() {
@Override
public void run() {
camera.setPreviewSize(cameraSize);
}
});
}

@Override
public Size getPreviewSize() {
return camera.getPreviewSize();
}

@Override
public void setDisplayOrientation(int displayOrientation) {
postTask(new Runnable() {
@Override
public void run() {
camera.setDisplayOrientation(displayOrientation);
}
});
}

@Override
public int getDisplayOrientation() {
return camera.getDisplayOrientation();
}

@Override
public void releaseCamera() {
if (handler == null) {
return;
}
postTask(new Runnable() {
@Override
public void run() {
camera.releaseCamera();
stopBackground();
}
});
}

@Override
public void addOnCameraListener(OnCameraListener onCameraListener) {
postTask(new Runnable() {
@Override
public void run() {
camera.addOnCameraListener(onCameraListener);
}
});
}

@Override
public void removeOnCameraListener(OnCameraListener onCameraListener) {
postTask(new Runnable() {
@Override
public void run() {
camera.removeOnCameraListener(onCameraListener);
}
});
}

@Override
public void removeAllOnCameraListener() {
postTask(new Runnable() {
@Override
public void run() {
camera.removeAllOnCameraListener();
}
});
}

/**

  • 获取Handler
    */
    private Handler getHandler() {
    if (thread == null || handler == null) {
    startBackground();
    }
    return handler;
    }

/**

  • 开启线程
    */
    private void startBackground() {
    stopBackground();
    thread = new HandlerThread(“camera_manager”);
    thread.start();
    handler = new Handler(thread.getLooper());
    }

/**

  • 关闭线程
    */
    private void stopBackground() {
    if (thread != null) {
    thread.quitSafely();
    thread = null;
    }
    if (handler != null) {
    handler = null;
    }
    }

/**

  • 执行任务
    */
    private void postTask(Runnable runnable) {
    getHandler().post(runnable);
    }
    }

注意到,CameraManager内部开启了Handler,目的是让相机的相关操作都在子线程进行

接下来可以具体实现Camera1

同样,我们新建Camera1,并实现ICamera接口

三、Camera1

全局变量

/**

  • Camera
    /
    private Camera camera;
    /
    *
  • 预览尺寸
    /
    private Size cameraSize = new Size(-1, -1);
    /
    *
  • 默认摄像头方向
    /
    private int facing = CameraConstants.facing.BACK;
    /
    *
  • 旋转角度
    */
    private int displayOrientation = -1;

打开相机

public void openCamera(int facing, Activity activity, SurfaceTexture surfaceTexture) {
// 先关闭相机
closeCamera();
// 判断是否存在摄像头
int cameraNum = Camera.getNumberOfCameras();
if (cameraNum <= 0) {
onCameraError(new IllegalStateException(“camera num <= 0”));
return;
}
// 检查传入的facing
int cameraIndex = -1;
if (facing == CameraConstants.facing.BACK) {
cameraIndex = Camera.CameraInfo.CAMERA_FACING_BACK;
} else if (facing == CameraConstants.facing.FRONT) {
cameraIndex = Camera.CameraInfo.CAMERA_FACING_FRONT;
}
if (cameraIndex == -1) {
onCameraError(new IllegalStateException(“camera facing exception”));
return;
}
// 判断摄像头个数,以决定使用哪个打开方式
if (cameraNum >= 2) {
camera = Camera.open(cameraIndex);
} else {
camera = Camera.open();
}
// 判断Camera是否初始化成功
if (camera == null) {
onCameraError(new IllegalStateException(“camera is null”));
return;
}
this.facing = facing;
try {
// 获取摄像头参数
Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> previewSizeList = parameters.getSupportedPreviewSizes();
if (cameraSize.getWidth() <= 0 || cameraSize.getHeight() <= 0) {
Camera.Size size = findTheBestSize(previewSizeList,
activity.getResources().getDisplayMetrics().widthPixels,
activity.getResources().getDisplayMetrics().heightPixels);
cameraSize.setWidth(size.width);
cameraSize.setHeight(size.height);
}
// 设置预览尺寸
parameters.setPreviewSize(cameraSize.getWidth(), cameraSize.getHeight());
// 这里设置使用的对焦模式
if (this.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
// 设置摄像头参数
camera.setParameters(parameters);
camera.setPreviewTexture(surfaceTexture);
if (displayOrientation < 0) {
displayOrientation = CameraUtils.getDisplayOrientation(activity, cameraIndex);
}

Android Camera1相机预览相关推荐

  1. Android Camera2 相机预览、获取数据

    Camera2简要说明 在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2),大幅提高了A ...

  2. android自定义相机预览尺寸,相机在Android中,如何获得最佳尺寸,预览尺寸,图片尺寸,视图尺寸,图像扭曲...

    混合来自OpenGL和 Android相机的视图时图像失真,以便在使用takepicture方法时获取两者的图像.我查了一下,发现相机图片设置为640X480,openGL视图和相机预览都设置为128 ...

  3. android+相机画面旋转,Android:相机预览的屏幕方向/旋转

    我已经创建了一个相机应用程序,我想让我的应用程序在所有4个可能的方向转换,并相应地更新相机预览.因为我已经使用我从以下复制的以下方法: Android – Camera preview is side ...

  4. android 圆形相机预览拍照_Android多种方式实现相机圆形预览

    最终效果图如下: 一.为预览控件设置圆角 public RoundTextureView(Context context, AttributeSet attrs) { super(context, a ...

  5. android 圆形相机预览拍照_Android多种方式实现相机圆形预览的示例代码

    效果图如下: 一.为预览控件设置圆角 public RoundTextureView(Context context, AttributeSet attrs) { super(context, att ...

  6. Android Camera2相机预览画面放大缩小(数码变焦DigitalZoom)功能实现

    一.前言 Android自定义相机开发中,常常会有通过手势放大或缩小相机预览画面的需求,即数码变焦DigitalZoom. 二.接口说明 1. 获取最大的放大倍数 float maxZoom = mC ...

  7. Android Camera相机预览,拍照 ,横屏竖屏的处理

    功能分别是: 1.竖屏的前置,后置显示 加 拍照 2.横屏的前置,后置显示 加 拍照 整个项目的代码贴出来了,里面加了有备注,不理解的也可以去参考官网点击跳转到官网 首先选择前置后置布局效果如下 布局 ...

  8. Android调用相机预览黑屏app passed NULL surface解决

    由于项目需求,要实现一个调用相机拍照然后将矩形框中的部分切割出来的功能,于是在网上找了 一个PlayCamera的demo程序.但运行的时候发现,只有第一次安装上时拍照界面能成功预览,一旦用back按 ...

  9. android编辑相机预览,为TextureView裁剪照相机预览

    由@Romanski提供的早期解决scheme工作正常,但随着裁剪而缩放. 如果您需要进行缩放以适应,请使用以下解决scheme. 每当表面视图改变时调用updateTextureMatrix:即在o ...

最新文章

  1. html5拖动图像的关键字,6.7 拖放图像 - HTML5 Canvas 实战
  2. PHP 如何得到当前页面中所有已定义的变量和常量
  3. 使用JScript设置SVN客户端hook
  4. Convex Hull (ACM-ICPC 2018 沈阳赛区网络预赛) 存个公式
  5. oracle 对两列加唯一性束_oracle中创建unique唯一约束(单列和多列) 。
  6. MySQL主从同步(三)——M-S-S架构配置实战
  7. quartus驱动无法识别分析
  8. PowerVR SGX
  9. 安卓面试中高级安卓开发工程师总结之——如何写一份让HR主动邀请你面试的简历
  10. 男 女 java 枚举_献给我老公 - Java枚举类型
  11. 【天光学术】信息管理论文:计算机信息管理应用于网络安全的策略(节选)
  12. ipv4和ipv6与int互转通用处理方式
  13. Java祝福生日快乐小程序
  14. 收藏 | 产品经理不可不知的 7 种技术思维
  15. ZOJ 3864 Quiz for EXO-L
  16. 微信硬件蓝牙设备开发之设备解绑(13)
  17. 合宙ESP32C3上手使用
  18. php判断百度ua展示不同页面,通过UA或反查IP两种方法识别百度蜘蛛【官方说法】...
  19. Proteus 网络名的添加
  20. LUNA16结节可视化及世界(CT)坐标与体素(图像)坐标的转换

热门文章

  1. 九段HR,你在哪个段位?
  2. Vue模板字符串的使用,【html标签、Element-uivue template模板渲染】
  3. 微交互如何提高产品的使用体验
  4. 3D建模真的这么赚钱?副业收入2万,只要喜欢就能做
  5. 2021临沭一中高考成绩查询,临沭一中举行高2021届高考励志报告会
  6. AUTUSAR通信篇 - CAN网络通信(一:CanDrv)
  7. C语言怎么编译对称图形,汇编程序设计显示对称图形.doc
  8. 新手学习3D建模,弯道超车攻略!
  9. java精品项目源码第91期家庭理财系统
  10. 除了头像,还有哪些现象级NFT?| 国庆特辑