自定义相机

需求:

在页面上实时捕捉画面并预览,
在nfc打卡校验通过的时候自动拍照;
无法通过本地的相机实现该功能,只能自定义了

权限

   <uses-permission android:name="android.permission.CAMERA"/>
   //即使没有没有相机这个硬件也可以安装
   <uses-feature android:name="android.hardware.camera" android:required="false"/>
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

创建预览相机需要的surfaceview

public class CameraView extends SurfaceView implements SurfaceHolder.Callback{
    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraView(Context context, Camera camera) {
        super(context);
        mCamera = camera;
        mHolder=getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    //接口回调
    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        try {
            mCamera.setPreviewDisplay(surfaceHolder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.v("meee",getClass()+":\n"+"设置相机预览失败");
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
        if (mHolder.getSurface()==null)
            return ;

        mCamera.stopPreview();
        try {
            mCamera.setPreviewDisplay(surfaceHolder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.v("meee",getClass()+":\n"+"设置相机预览失败");
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
    }
}

页面

布局:
布局很简单,线性布局上方是一个framelayout下方是一个button
public class MainActivity extends AppCompatActivity {

    private FrameLayout fl;
    private Button btn;

    Camera mCamera;
    CameraView mCameraView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        if (!hasCamera(this)){
            Toast.makeText(getApplicationContext(),"开发板不支持相机",Toast.LENGTH_SHORT).show();
        }else {
            initCamera();
        }
    }

    private void initView() {
        fl = (FrameLayout) findViewById(R.id.fl);
        btn = (Button) findViewById(R.id.btn);
    }

    private void initCamera() {
        mCamera=getCameraInstance();
        mCameraView=new CameraView(this,mCamera);
        fl.addView(mCameraView);
    }

    //判断是否存在相机
    private boolean hasCamera(Context context) {
        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))
            return true;
        return false;
    }

    //获取相机
    public static Camera getCameraInstance() {
        Camera camera = Camera.open();
        return camera;
    }
}

添加拍照的回调

    //拍照的回调
    Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
            if (file == null) {
                Toast.makeText(getApplicationContext(), "读取权限异常", Toast.LENGTH_SHORT).show();
                return;
            }
            String pictureName = new DateFormat().format("yyyyMMddHHmmss",
                    new Date()).toString()
                    + ".png";
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(file + File.separator + pictureName);
                fos.write(data);
                fos.close();
                Log.v("meee", getClass() + ":\n" + "成功保存至" + file);
            } catch (FileNotFoundException e) {
                Log.v("meee", getClass() + ":\n" + "保存失败");
            } catch (IOException e) {
                Log.v("meee", getClass() + ":\n" + "保存失败");
            }
        }
    };

//在需要的时刻通过handler进行拍照
    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case TAKE_PHOTO:
                    mCamera.takePicture(null, null, mPictureCallback);
                    break;
            }
        }
    };

定时拍照

            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    mHandler.sendEmptyMessage(TAKE_PHOTO);
                }
            },10000);   
获取时间精确到秒
String pictureName = new DateFormat().format("yyyyMMdd-HH:mm:ss",
                    new Date()).toString()
                    + ".png";

设置摄像头的方向

       //获取摄像头的信息
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        //camreaId=0代表后置摄像头,1代表前置
        android.hardware.Camera.getCameraInfo(camreaId,cameraInfo);
        //获取当前页面的旋转角度
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        判断是否是前置摄像头
        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            Log.v("meee","qian");
            result = (cameraInfo.orientation + degree) % 360;
            result = (360 - result) % 360;
        } 

#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值