android获取手机摄像头

原创
2017/11/15 19:13
阅读数 2K

经过两天的努力终于找到了使用android获取摄像头的方法:

下面就详细介绍一下,获取摄像头的流程: 点击获取源代码

1.第一步,先获取摄像头的权限;

代码如下:(注:如果使用的是android studio的话把代码放到 <manifest>之后<application>之前,不然,会报错,因为获取不到权限)

<uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

2.创建布局文件:(注:最主要的是创建Surfaceview控件,因为他是用来接收由Camera传回来的数据的)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.xiao.cameratesttwo.MainActivity">

    <SurfaceView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/surfaceview"/>


    <LinearLayout

        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="vertical" >
        <Button
            android:id="@+id/btn_qiehua"
            android:text="切换摄像头"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"/>
        <Button
            android:id="@+id/btn_click"
            android:text="启动摄像头"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="400dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"/>
    </LinearLayout>

</RelativeLayout>

3.编写java代码:(注:要把camera类的open方法放到 try{}catch(){}里面的话需要使用Exception不能使用IOException,会报错)

代码如下:


import android.graphics.ImageFormat;

import android.hardware.Camera;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import android.view.SurfaceHolder;
import android.view.SurfaceView;

import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import java.util.Iterator;
import java.util.List;

public class MainActivity extends AppCompatActivity implements Camera.PreviewCallback {
    /**
     * 定义前后摄像头,0为后摄像头,1为前摄像头
     */
    public int  Camerafb =0;
    /**
     * 创建Camera对象
     * 用来获取摄像头
     */
    public Camera camera;
    /**
     * 创建surfaceview对象
     * 这个对象是用来显示从Camera返回的图像的
     */
    private SurfaceView surfaceview;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Window window = getWindow();//得到窗口
        requestWindowFeature(Window.FEATURE_NO_TITLE);//设置没有标题
        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//设置高亮
        setContentView(R.layout.activity_main);
        surfaceview = (SurfaceView) findViewById(R.id.surfaceview);//实例化surfaceview对象
        findViewById(R.id.btn_click).setOnClickListener(new View.OnClickListener() {//创建启动摄像头事件
            @Override
            public void onClick(View view) {
                initcamera();//初始化摄像头,并且把摄像头的图像返回给surfaceview控件
            }
        });
        findViewById(R.id.btn_qiehua).setOnClickListener(new View.OnClickListener() {//创建切换摄像头事件
            @Override
            public void onClick(View v) {
                //如果Camerafb的值为0的话,说明使用的是后置摄像头
                if(Camerafb ==0){
                    Camerafb=1;//把Camerafb的值改为1,则使用的是前置摄像头
                    initcamera();//初始化摄像头,并且把摄像头的图像返回给surfaceview控件
                    return;
                //如果Camerafb的值为1的话,说明使用的是前置摄像头
                }else if(Camerafb ==1) {
                    Camerafb = 0;//把Camerafb的值改为0,则使用的是后置摄像头
                    initcamera();//初始化摄像头,并且把摄像头的图像返回给surfaceview控件
                    return;
                }else{
                    return;
                }
            }
        });
    }

    /**
     * 初始化摄像头
     */
    public void initcamera(){

        try {
            //如果camera中有值的,则清空camera中的数据
            if(camera !=null){
                camera.stopPreview();
                camera.release();
                camera = null;
            }
            camera = Camera.open(Camerafb);//开启摄像头,open中需要赋值,0为后置摄像头,1为前置摄像头
            Camera.Parameters parameters= camera.getParameters();//从摄像头返回的数据
            parameters.setPreviewFormat(ImageFormat.NV21);//设置摄像头的预览帧格式
            camera.setDisplayOrientation(90);//调整相机拍到的图像旋转,不然竖着拿手机,图像是横着的
            parameters.setRotation(90);//调整的图像旋转,不然竖着拿手机,图像是横着的
            //获取尺寸的大小
            List<Camera.Size> sizeList = parameters.getSupportedPictureSizes();
            if(sizeList.size()>1){
                Iterator<Camera.Size> itor = sizeList.iterator();
                while (itor.hasNext()){
                    Camera.Size cur =itor.next();
                    Log.i("jw","val"+cur);
                }
            }
            //设置图像预览的尺寸
            parameters.setPreviewSize(640, 480);
            parameters.setPictureSize(640, 480);
            camera.setParameters(parameters);//设置摄像头需要的数据
            camera.setPreviewDisplay(surfaceview.getHolder());//使用getHolder方法把数据返回给surfaceview
            camera.setPreviewCallback(this);//摄像头的回调
            camera.startPreview();//开始预览取景
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //释放摄像头资源
    public void destroyCamera(){
        if(camera==null){
            return ;
        }
        camera.setPreviewCallback(null);
        camera.stopPreview();
        camera.release();
        camera =null;
    }


    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {

    }

    @Override
    protected void onStop() {
        super.onStop();
        destroyCamera();
    }
}

4.效果图如下:

如果有什么不懂的可以来问我。(由于android5.0的ipa上面将来不让使用android.hardware.Camera类,所以我会尽快的分享使用android.hardware.Camera2拍照和录像)

下一篇分享实现用摄像头去拍照录视频。

展开阅读全文
加载中

作者的其它热门文章

打赏
1
0 收藏
分享
打赏
2 评论
0 收藏
1
分享
返回顶部
顶部