surfaceview和camera实现自定义相机

本文分享了使用SurfaceView和Camera在Android中实现自定义相机的步骤,包括设置SurfaceHolder、实现MySurfaceHolderCallBack以获取屏幕宽高,以及添加拍照功能。记得在Android 6.0及以上版本处理动态权限。
摘要由CSDN通过智能技术生成

最近项目要求自定义相机,所以记录分享一下实现过程

第一步:首先是设置holder

        mHolder = mDiagnosSurfaceview.getHolder();

        mHolder.addCallback(new MySurfaceHolderCallback());

        mHolder.setKeepScreenOn(true);

        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

第二步然后就是写MySurfaceHolderCallBack

public class MySurfaceHolderCallback implements SurfaceHolder.Callback
//自定义MySurfaceHolderCallback 实现 surfaceholder.callback 复写三个方法

//MySurfaceHolderCallback的第一个方法surfaceCreated的内容

            mHolder = holder;//这个很重要是为了在返回桌面或者从别的类返回之后还可以看到预览界面,不然就会黑屏的

            mCamera = Camera.open();

            if (mCamera != null) {

                Camera.Parameters parameters = mCamera.getParameters();

                parameters.setJpegQuality(100);
                //mHeightPixels,mWidthPixels两个是测量的不同手机的宽高,之前是写死的1920*1080
                //结果在有些手机上面会出现黑屏的现象所以这一步很重要具体怎么获得的下面会给出代码
                parameters.setPreviewSize(mHeightPixels, mWidthPixels);

                parameters.setPictureFormat(ImageFormat.JPEG);

                parameters.setPictureSize(mHeightPixels, mWidthPixels);

                mCamera.setDisplayOrientation(90);

                //设置自动对焦
                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);

                mCamera.setParameters(parameters);

                try {
                    mCamera.setPreviewDisplay(mHolder);
                } catch (IOException e) {
                    e.printStackTrace();
                }



                mCamera.startPreview();
//MySurfaceHolderCallback的第二个方法surfaceChanged里面的内容

mHolder = holder;//这个方法也是在返回桌面或者从别的类返回之后还可以看到预览界面,不然就会黑屏的

//MySurfaceHolderCallback的第三个方法surfaceDestroyed里面的内容
//主要是释放资源
if (mCamera != null) {

                mCamera.stopPreview();

                mCamera.release();

                mCamera = null;

                System.out.println("eee");

            }

            mHolder = null;

            if (mHolder != null) {

                mHolder = null;

                System.out.println("rrr");

            }

下面的代码是怎么获取屏幕的宽高

WindowManager wm = getWindowManager();

        Display display = wm.getDefaultDisplay();

        DisplayMetrics metrics = new DisplayMetrics();

        display.getMetrics(metrics);

        //屏幕的宽
        mWidthPixels = metrics.widthPixels;

        //屏幕的高
        mHeightPixels = metrics.heightPixels;

好了,预览的代码写完了,接下来是拍照了

在需要点击拍照的点击事件下面写如下方法

“`
private void startCemera() {
Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {

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

            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

            Matrix matrix = new Matrix();

            matrix.reset();

            //又时候要求转换摄像头,会发现转到前置摄像头的时候显示的照片是倒着的,所以有这个判断前置就rotate
            //270度,后置的rotate90度
            if (isBackCamera) {
                matrix.postRotate(90);
            } else {
                matrix.postRotate(270);
            }


            Bitmap bMapRotate = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

            //不做如上处理,竖着拍照显示的照片是横向的,通过matrix对bitmap的处理照片正着拍显示的时候是正着的
            //横着拍就是横着的
            bitmap = bMapRotate;

            mCamera.stopPreview();

            String saveName = Environment.getExternalStorageDirectory().getAbsolutePath() + "/aaaa/" + System.currentTimeMillis() + ".jpg";

            File file = new File(saveName);

            if (!file.exists()) {
                file.getParentFile().mkdirs();
            }


            //将图片写入文件路径为savename的文件里面
            try {
                FileOutputStream fout = new FileOutputStream(file);

                BufferedOutputStream bos = new BufferedOutputStream(fout);

                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);

                bos.flush();

                bos.close();

                //跳转到展示图片的类  通过glide展示
                //Glide.with(this).load(mFilepath).fitCenter().into(mShowIv);

                Intent in = new Intent(DiagnosisBeginActivity.this, ShowPicActivity.class);

                in.putExtra("filepath", saveName);

                startActivity(in);

            } catch (Exception e) {
                e.printStackTrace();
            }


        }
    };

    mCamera.takePicture(null, null, pictureCallback);
}

好了,自定义相机基本步骤全部写完了,记得6.0动态权限的添加,我这里就不赘述了
第一次写博客,写的不好的地方大家多多指正,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值