全网最简单实用Android摄像头开发,同时预览多个摄像头,双目摄像头,同时打开手机前后摄像头(红外摄像头、人脸识别、活体检测、Android Camera、缩放、焦距、旋转、镜像、截图保存)

这篇具有很好参考价值的文章主要介绍了全网最简单实用Android摄像头开发,同时预览多个摄像头,双目摄像头,同时打开手机前后摄像头(红外摄像头、人脸识别、活体检测、Android Camera、缩放、焦距、旋转、镜像、截图保存)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

如果你受够了网上那些乱七八糟的代码,你可以了解下我这个,能同时打开多个摄像头,在界面上预览,并且可以取得摄像头数据,byte[] 转为 Bitmap,保存为 jpg图片。

最近我们的某个项目要加上Android人脸识别,虽然有别人写好的“考勤”、“门口闸机”这些,但不能直接用于我们的项目,我们有自己的业务需求。

我们机器有3个摄像头,在进行人脸识别的时候,3个摄像头都要处于工作状态;分别是:一个主摄像头本来就一直处于拍照检测中的,另外的双目摄像头,一个用于人脸检测,另一个是红外摄像头于用进行活体检测。

当我开始调整的时候,才发现原来用的“androidx.camera”并不能同时打开多个摄像头,然后我去了解 camera2,发现使用比较复杂,我的想法是,简单实用就好,并不要非常强大的各种功能,后来我再去了解"camera1",即 “android.hardware.Camera”,这个虽然现在被弃用了,但是还能用,而且我感觉这个比较好理解,基于它我实现了需求。

如果你想要快速获得摄像头数据(甚至不用在界面显示预览),像下面这样即可:

    android.hardware.Camera mCamera;
    android.graphics.SurfaceTexture mSurface;

    /**
     * 摄像头快速预览并取得数据
     * 注意:mCamera和mSurface不要在本方法内定义
     */
    private void startCamera() {
        int cameraId = 0;
        try {
            // 打开相机
            mCamera = Camera.open(cameraId);
            // 设置图像尺寸
            Camera.Parameters params = mCamera.getParameters();
            params.setPreviewSize(640, 480);
            mCamera.setParameters(params);
            // 设置预览视图
            mSurface = new SurfaceTexture(0);
            mCamera.setPreviewTexture(mSurface);
            // 设置图像数据回调
            mCamera.setPreviewCallback(new Camera.PreviewCallback() {
                @Override
                public void onPreviewFrame(byte[] data, Camera camera) {
                    // 取得图像数据,每一帧图像都回调到这里,在这里做图像处理
                    // 该方法高频调用,用RXJava做流控,data转换为Bitmap或Mat等
                }
            });
            // 开启预览
            mCamera.startPreview();
        } catch (Exception ignored) {
            // 发生异常
        }
    }

下面是我摄像头的相关代码,有需求的朋友可参考:

package cn.example.test.facesdk.camera;

import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.view.TextureView;

import java.io.IOException;
import java.util.List;

public class PreviewCamera {

    private Camera mCamera;
    private boolean mirror = false; // 镜像(左右翻转)
    private int rotate = -1; // 旋转(相机传感器方向相对于设备自然方向的角度)
    private int zoom = -1; // 焦距(有些摄像头可能不支持)

    public void setMirror(boolean mirror) {
        this.mirror = mirror;
    }

    public void setRotate(int rotate) {
        this.rotate = rotate;
    }

    public void setZoom(int zoom) {
        this.zoom = zoom;
    }

    public void startCamera(TextureView textureView, int cameraIndex, int width, int height, ICallback callback) {
        stopCamera();
        try {
            mCamera = Camera.open(cameraIndex);
            checkPreviewSize(width, height);
            // 设置参数(尺寸、对焦、焦距、旋转)
            Camera.Parameters params = mCamera.getParameters();
            //List<Integer> list = params.getSupportedPreviewFormats();
            params.setPreviewSize(width, height);
            List<String> focusModes = params.getSupportedFocusModes();
            if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
                params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
            }
            if (this.zoom >= 0 && params.isZoomSupported() && this.zoom <= params.getMaxZoom()) {
                params.setZoom(this.zoom);
                mCamera.setParameters(params);
            }
            mCamera.setParameters(params);
            if (this.rotate >= 0) {
                mCamera.setDisplayOrientation(this.rotate);
            }
            // 预览初始化(左右翻转)
            initPreview(textureView);
            if (this.mirror) {
                textureView.setRotationY(180);
            }
            // 回调
            mCamera.setPreviewCallback(new Camera.PreviewCallback() {
                @Override
                public void onPreviewFrame(byte[] data, Camera camera) {
                    if (callback != null) {
                        callback.onData(data, camera);
                    }
                }
            });
            if (callback != null) {
                callback.onSucc(mCamera);
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (callback != null) {
                callback.onError(e);
            }
        }
    }

    public void stopCamera() {
        try {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        } catch (Exception e) {
        }
    }

    private void checkPreviewSize(int width, int height) throws Exception {
        boolean sizeOk = false;
        List<Camera.Size> sizeList = mCamera.getParameters().getSupportedPreviewSizes();
        for (Camera.Size size : sizeList) {
            if (size.width == width && size.height == height) {
                sizeOk = true;
            }
        }
        if (!sizeOk) {
            throw new Exception(String.format("不支持该预览尺寸: [%d,%d]", width, height));
        }
    }

    private TextureView initPreview(TextureView textureView) {
        textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
                try {
                    if (mCamera != null) {
                        mCamera.setPreviewTexture(surfaceTexture);
                        mCamera.startPreview();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
                stopCamera();
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {

            }
        });
        return textureView;
    }

    public interface ICallback {
        void onSucc(Camera camera);

        void onData(byte[] data, Camera camera);

        void onError(Exception e);
    }
}

上面代码直接放到你项目即可,使用也非常简单明了,如下:

package cn.example.test.Activity;

import android.graphics.Bitmap;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.TextureView;

import cn.example.test.Activity.Base.BaseActivity;
import cn.example.test.R;
import cn.example.test.facesdk.camera.PreviewCamera;
import cn.example.test.facesdk.camera.PreviewCameraUtils;

public class MainActivity extends BaseActivity {

    PreviewCamera previewCamera1 = new PreviewCamera();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onResume() {
        super.onResume();
        start();
    }

    @Override
    protected void onPause() {
        super.onPause();
        stop();
    }

    private void start() {
        TextureView textureView1 = findViewById(R.id.camera_preview);

        // 设置镜像(左右翻转)
        previewCamera1.setMirror(false);

        // 设置旋转角度
        //previewCamera1.setRotate(90);

        // 设置焦距
        //previewCamera1.setZoom(50);

        previewCamera1.startCamera(textureView1, 0, 640, 480, new PreviewCamera.ICallback() {
            @Override
            public void onData(byte[] data, Camera camera) {
                dealData1(data, camera);
            }

            @Override
            public void onSucc(Camera camera) {
            }

            @Override
            public void onError(Exception e) {
            }
        });
    }

    private void stop() {
        previewCamera1.stopCamera();
    }

    long lastTime1 = 0;

    private void dealData1(byte[] data, Camera camera) {
        // 控制下频率
        long currTime = System.currentTimeMillis();
        if (currTime - lastTime1 < 5000) {
            return;
        }
        lastTime1 = currTime;
        // 转换为Bitmpa
        Bitmap bitmap = PreviewCameraUtils.cameraDataToBitmap(data, camera);
        // 旋转&翻转
        bitmap = PreviewCameraUtils.bitmapXform(bitmap, 270, false, true);
        // 保存为jpg
        String path = PreviewCameraUtils.getSDCardPath() + "/" + System.currentTimeMillis() + ".jpg";
        PreviewCameraUtils.saveBitmapToFile(bitmap, path);
    }
}

上面就是核心的代码,已经可以把摄像头使用起来了,下面放几个常用的帮助方法:

package cn.example.test.facesdk.camera;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.os.Environment;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class PreviewCameraUtils {

    public static Bitmap cameraDataToBitmap(byte[] data, Camera camera) {
        Camera.Parameters parameters = camera.getParameters();
        int width = parameters.getPreviewSize().width;
        int height = parameters.getPreviewSize().height;
        int format = parameters.getPreviewFormat();
        Bitmap bitmap = yuvToBitmap(data, format, width, height);
        return bitmap;
    }

    /**
     * 摄像头数据转换为Bitmap
     *
     * @param data
     * @param format
     * @param width
     * @param height
     * @return
     */
    public static Bitmap yuvToBitmap(byte[] data, int format, int width, int height) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        YuvImage yuvImage = new YuvImage(data, format, width, height, null);
        yuvImage.compressToJpeg(new Rect(0, 0, width, height), 100, out);
        byte[] imageBytes = out.toByteArray();
        return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
    }

    /**
     * Bitmap进行旋转和翻转
     *
     * @param bitmap
     * @param rotate        旋转的角度
     * @param leftRightTurn 是否左右翻转
     * @param upDownTurn    是否上下翻转
     * @return
     */
    public static Bitmap bitmapXform(Bitmap bitmap, int rotate, boolean leftRightTurn, boolean upDownTurn) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Matrix matrix = new Matrix();
        if (leftRightTurn) {
            matrix.preScale(-1f, 1f);
        }
        if (upDownTurn) {
            matrix.preScale(1f, -1f);
        }
        if (rotate > 0) {
            matrix.postRotate(rotate);
        }
        Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
        return rotatedBitmap;
    }

    /**
     * 把Bitmap保存为jpg文件
     *
     * @param bitmap
     * @param filePath 绝对路径
     */
    public static void saveBitmapToFile(Bitmap bitmap, String filePath) {
        File file = new File(filePath);
        try {
            // 创建文件输出流
            FileOutputStream outputStream = new FileOutputStream(file);
            // 将bitmap写入输出流中
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
            // 刷新缓冲区
            outputStream.flush();
            // 关闭输出流
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 取得SDCard根路径
     *
     * @return
     */
    public static String getSDCardPath() {
        return "" + Environment.getExternalStorageDirectory();
    }

}

另外,记得声明权限,示例:

    <uses-feature
        android:name="android.hardware.camera.any"
        android:required="true" />
    <uses-permission android:name="android.permission.CAMERA" />
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED) {
            requestPermissions(new String[]{Manifest.permission.CAMERA}, CAMERA_PERMIS_CODE);
        } else {
            
        }

-------------------(完)-------------------文章来源地址https://www.toymoban.com/news/detail-717283.html

到了这里,关于全网最简单实用Android摄像头开发,同时预览多个摄像头,双目摄像头,同时打开手机前后摄像头(红外摄像头、人脸识别、活体检测、Android Camera、缩放、焦距、旋转、镜像、截图保存)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • android 13.0 Camera2 去掉后置摄像头 仅支持前置摄像头功能

    在定制化13.0系统rom定制化开发中,当产品只有一个前置摄像头单摄像头,这时调用相机时就需要默认打开前置摄像头就需要来看调用摄像头这块的代码,屏蔽掉后置摄像头的调用api就可以了,接下来就来具体实现相关功能的开发 Camera2 API 概述 Camera2 API的包名是android.hardware

    2024年01月21日
    浏览(50)
  • Android——调用摄像头拍照

    首先修改activity_main.xml 如下: 添加一个按钮和图片。 我们的逻辑功能是: 点击按钮后打开相机 相机拍照后图片返回到图片里 由于代码比较长切复杂,我会一步步讲解以便于我的理解。(没错就是我的) 首先我们需要为Button注册点击事件 我们要创建一个文件存放我们拍照的

    2024年02月14日
    浏览(26)
  • 把Android手机变成电脑摄像头

    使用 DroidCam,你可以将手机作为电脑摄像头和麦克风。一则省钱,二则可以在紧急情况下使用,比如要在电脑端参加一个紧急会议,但电脑却没有摄像头和麦克风。 DroidCam 的安卓端分为免费的 DroidCam 版和收费的 DroidCamX版(支持高清),都需要去谷歌商店下载,且需要绑定手

    2024年02月11日
    浏览(40)
  • 【树莓派笔记】树莓派摄像头的简单使用

    这里使用的是树莓派CSI (Camera Serial Interface)摄像头。引脚面朝micoHDMI接口处。关机后安装,热插拔可能无法检测到。 终端输入   之后重启即可 命令行用 raspistill 使用摄像头进行拍照。 可以用 -e png 指定生成jpg、png、gif、bmp格式的图片,后三种无损,生成速度会慢些。 raspiy

    2024年02月15日
    浏览(40)
  • Android:实现手机前后摄像头预览双开

    本博文讲解如何实现 手机前后两颗摄像头同时预览并显示 我之前博文《OpenGLES:GLSurfaceView实现Android Camera预览》对单颗摄像头预览做过详细讲解,而前后双摄实现原理其实也并不复杂,粗糙点说就是把 单摄像头预览流程写两遍 。 与之前博文中使用 GLSurfaceView 实现相机预览不

    2024年02月06日
    浏览(31)
  • Android-WebRTC-实现摄像头显示

    EglBase是什么? 它提供了一个接口,用于在Android平台上创建和管理EGL(嵌入式系统图形库)上下文,以便在WebRTC中进行图像和视频的处理和渲染。 Capturer, Source, Track, Sink分别是什么? Capturer(采集器)是指用于采集音频或视频数据的设备或软件。它可以是麦克风、摄像头或其

    2024年02月15日
    浏览(37)
  • android 12.0Camera旋转摄像头方向

    在12.0 产品定制化开发中,由于摄像头方向默认是竖屏的,但是平板电脑一般都是要横屏拍摄的 所以就需要旋转摄像头方向,来适应拍摄的需要,这就需要在Camera中打开摄像头的时候,设置参数旋转摄像头方向

    2024年02月13日
    浏览(33)
  • Android修行手册-多路USB外接摄像头

    点击跳转=Unity3D特效百例 点击跳转=案例项目实战源码 点击跳转=游戏脚本-辅助自动化 点击跳转=Android控件全解手册 点击跳转=Scratch编程案例 点击跳转=软考全系列 专注于 Android/Unity 和各种游戏开发技巧,以及 各种资源分享 (网站、工具、素材、源码、游戏等) 有什么需要欢

    2024年02月07日
    浏览(39)
  • RK3568-android11-适配ov13850摄像头

    参考链接 相关概念 相关接口 相关协议 图像格式

    2024年02月09日
    浏览(49)
  • Android实时获取摄像头画面传输至PC端

    最近在做一个PC端小应用,需要获取摄像头画面,但是电脑摄像头像素太低,而且位置调整不方便,又不想为此单独买个摄像头。于是想起了之前淘汰掉的手机,成像质量还是杠杠的,能不能把手机摄像头连接到电脑上使用呢?经过搜索,在网上找到了几款这类应用,但是都

    2024年02月12日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包