Android Camera1相机预览

  • CameraX

本文重点在于说明Camera1的使用

二、CameraManager

可以对相机的使用进行封装,只需要定义相机的相关操作,具体实现是Camera1,或Camera2,亦或是CameraX,都无需外部进行修改,只需内部进行定义,首先,先定义相机的相关操作接口ICamera

相机接口

public interface ICamera {
/**

  • 打开相机
    /
    void openCamera(Activity activity, SurfaceTexture surfaceTexture);
    /
    *
  • 打开相机
    /
    void openCamera(int facing, Activity activity, SurfaceTexture surfaceTexture);
    /
    *
  • 关闭相机
    /
    void closeCamera();
    /
    *
  • 切换相机
    /
    void switchCamera();
    /
    *
  • 切换相机
    /
    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 implements 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是否初始化成功

最后

文章不易,如果大家喜欢这篇文章,或者对你有帮助希望大家多多点赞转发关注哦。文章会持续更新的。绝对干货!!!

  • Android进阶学习全套手册
    关于实战,我想每一个做开发的都有话要说,对于小白而言,缺乏实战经验是通病,那么除了在实际工作过程当中,我们如何去更了解实战方面的内容呢?实际上,我们很有必要去看一些实战相关的电子书。目前,我手头上整理到的电子书还算比较全面,HTTP、自定义view、c++、MVP、Android源码设计模式、Android开发艺术探索、Java并发编程的艺术、Android基于Glide的二次封装、Android内存优化——常见内存泄露及优化方案、.Java编程思想 (第4版)等高级技术都囊括其中。

  • Android高级架构师进阶知识体系图
    关于视频这块,我也是自己搜集了一些,都按照Android学习路线做了一个分类。按照Android学习路线一共有八个模块,其中视频都有对应,就是为了帮助大家系统的学习。接下来看一下导图和对应系统视频吧!!!

  • Android对标阿里P7学习视频

  • BATJ大厂Android高频面试题
    这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

Android高频面试题**
这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等
[外链图片转存中…(img-8H3Y2Nbt-1714272963405)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值