android开发之textureview绑定camera实现拍照功能

转载请注明出处:http://blog.csdn.net/sw950729/article/details/51994735
本文出自:马云飞的博客

最近要整理的东西比较多,比较乱,一个一个来把,自定义layout实现recyclerview的下拉刷新和上拉加载还是没有什么思路。刚好前几天上司让我做几个关于camera的界面,我就先介绍下camera把,android4.0后更新了一个控件,textureview,个人感觉而言,它比surfaceview好用很多,不多说,上代码:

textureview.addOnLayoutChangeListener(this);
        matrix = new Matrix();
        textureview.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {


            public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
                camera = Camera.open(0);
                RectF previewRect = new RectF(0, 0, mWidth, mHeight);

                double aspect = (double) mPreviewWidth / mPreviewHeight;

                if (getResources().getConfiguration().orientation
                        == Configuration.ORIENTATION_PORTRAIT) {
                    aspect = 1 / aspect;
                }

                if (mWidth < (mHeight * aspect)) {
                    mDisplayWidth = mWidth;
                    mDisplayHeight = (int) (mHeight * aspect + .5);

                } else {
                    mDisplayWidth = (int) (mWidth / aspect + .5);
                    mDisplayHeight = mHeight;

                }

                RectF surfaceDimensions = new RectF(0, 0, mDisplayWidth, mDisplayHeight);
                matrix.setRectToRect(previewRect, surfaceDimensions, Matrix.ScaleToFit.FILL);

//                textureview.setTransform(matrix);
                param = camera.getParameters();
                int displayRotation = 0;

                WindowManager windowManager = (WindowManager) PhotoActivity.this
                        .getSystemService(Context.WINDOW_SERVICE);
                int rotation = windowManager.getDefaultDisplay().getRotation();


                switch (rotation) {
                    case Surface.ROTATION_0:
                        displayRotation = 0;
                        break;
                    case Surface.ROTATION_90:
                        displayRotation = 90;
                        break;
                    case Surface.ROTATION_180:
                        displayRotation = 180;
                        break;
                    case Surface.ROTATION_270:
                        displayRotation = 270;
                        break;
                }

                Camera.CameraInfo info = new Camera.CameraInfo();
                Camera.getCameraInfo(0, info);

                if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {

                    orientation = (info.orientation - displayRotation + 360) % 360;
                } else {
                    orientation = (info.orientation + displayRotation) % 360;
                    orientation = (360 - orientation) % 360;
                }

                param.setPreviewSize(mPreviewWidth, mPreviewHeight);
                camera.setParameters(param);
                camera.setDisplayOrientation(orientation);
                try {
                    camera.setPreviewTexture(surfaceTexture);
                } catch (IOException e) {
                }
                camera.startPreview();
//                textureview.setAlpha(1.0f);
//                textureview.setRotation(90.0f);
            }

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

            }

            public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
//                camera.setPreviewCallback(null);
//                camera.stopPreview();
//                camera.release();
                surfaceTexture.release();
                camera = null;
                return true;
            }

            public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {

            }
        });

上面代码主要是讲camera和textureview绑定起来,以及textureview的呈现区域不变形。
priview的宽高我设置的是640*480,正常比例是0.75(480*640).因为摄像头是要通过旋转90°来显示,所以我把他的宽高640*480.

下面代码主要是实现,主副摄像头的切换,以及开关闪光灯。

 @OnClick({R.id.back, R.id.camera_head, R.id.light, R.id.shot})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.back:
                finish();
                break;
            case R.id.camera_head:
                if (!isFront) {
                    camera.stopPreview();
                    camera.release();
                    camera = Camera.open(1);
                    param = camera.getParameters();
                    param.setPreviewSize(mPreviewWidth, mPreviewHeight);
                    camera.setParameters(param);
                    camera.setDisplayOrientation(orientation);
                    try {
                        camera.setPreviewTexture(textureview.getSurfaceTexture());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    camera.startPreview();
                    isFront = true;
                } else {
                    camera.stopPreview();
                    camera.release();
                    camera = Camera.open(0);
                    param = camera.getParameters();
                    param.setPreviewSize(mPreviewWidth, mPreviewHeight);
                    camera.setParameters(param);
                    camera.setDisplayOrientation(orientation);
                    try {
                        camera.setPreviewTexture(textureview.getSurfaceTexture());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    camera.startPreview();
                    isFront = false;
                }
                break;
            case R.id.light:
                if (!isLight) {
                    parameter = camera.getParameters();
                    parameter.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                    camera.setParameters(parameter);
                    light.setImageResource(R.drawable.open_light);
                    isLight = true;
                } else {
                    parameter.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                    camera.setParameters(parameter);
                    light.setImageResource(R.drawable.close_light);
                    isLight = false;
                }
                break;
            case R.id.shot:
                camera.takePicture(null, null, this);
                break;
        }

camera.takepicture(),就是进行拍照了,这个很简单,把他保存在sd的路径就可以了。代码如下:

 // data是字节数据,将其解析成位图
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            Matrix matrix = new Matrix();
            // 使图片旋转90°
            matrix.preRotate(90);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                    bitmap.getHeight(), matrix, true);
            // 保存图片到sdcard

            // 获取SD卡的路径
            File file = new File(Environment.getExternalStorageDirectory(),
                    System.currentTimeMillis() + ".jpg");
            FileOutputStream outputStream = new FileOutputStream(file);
            // 压缩图片,不压缩是100,表示压缩率为0
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
            outputStream.close();

            // 停止预览
            camera.stopPreview();
            camera.release();
            camera = Camera.open(0);
            param = camera.getParameters();
            param.setPreviewSize(mPreviewWidth, mPreviewHeight);
            camera.setParameters(param);
            camera.setDisplayOrientation(orientation);
            try {
                camera.setPreviewTexture(textureview.getSurfaceTexture());
            } catch (IOException e) {
                e.printStackTrace();
            }
            camera.startPreview();// 处理完数据之后可以预览
            Log.e("pig", file.getPath());
        } catch (Exception e) {
            e.printStackTrace();
        }

当然,最后还有textureview的layout变化的宽高改变,以及一些权限,代码如下:

 public void onLayoutChange(View v, int left, int top, int right,
                               int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        mWidth = right - left;
        mHeight = bottom - top;
    }
 <uses-permission android:name="android.permission.FLASHLIGHT" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.RECORD_VIDEO"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

这样,一个camera拍照功能就解决了。比较麻烦就是textureview使camera变形的问题。
我的android交流群:232748032。

你可能感兴趣的:(android进阶,android开发)