Android自定义照相机 预览拍照 切换前后置摄像头

来源:互联网 发布:爱上学软件下载 编辑:程序博客网 时间:2024/05/01 06:16

转自:http://my.eoe.cn/761385/archive/4226.html

Android提供了Camera来控制拍照,步骤如下:
(1)调用Camera的open()方法打开相机。
(2)调用Camera的getParameters()获取拍照参数,该方法返回一个Cmera.Parameters对象。
(3)调用Camera.Parameters对象对照相的参数进行设置。
(4)调用Camera的setParameters(),并将Camera.Parameters对象作为参数传入,这样就可以对拍照进行参数控制,Android2.3.3以后不用设置。
(5)调用Camerade的startPreview()的方法开始预览取景,在之前需要调用Camera的setPreviewDisplay(SurfaceHolder holder)设置使用哪个SurfaceView来显示取得的图片。
(6)调用Camera的takePicture()方法进行拍照。
(7)程序结束时,要调用Camera的stopPreview()方法停止预览,并且通过Camera.release()来释放资源。

需要赋予Camera的权限:

123
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><uses-permission android:name="android.permission.CAMERA"/>

下面上代码:

  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
package com.lyj.camera;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import android.app.Activity;import android.content.pm.ActivityInfo;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.PixelFormat;import android.hardware.Camera;import android.hardware.Camera.AutoFocusCallback;import android.hardware.Camera.CameraInfo;import android.hardware.Camera.Parameters;import android.hardware.Camera.PictureCallback;import android.os.Bundle;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.View.OnClickListener;import android.view.Window;import android.view.WindowManager;import android.widget.ImageButton;import android.widget.ImageView;public class MyCameraActivity extends Activity implements SurfaceHolder.Callback {    private ImageView back, position;//返回和切换前后置摄像头    private SurfaceView surface;    private ImageButton shutter;//快门    private SurfaceHolder holder;    private Camera camera;//声明相机    private String filepath = "";//照片保存路径    private int cameraPosition = 1;//0代表前置摄像头,1代表后置摄像头    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);//没有标题        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏        this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//拍照过程屏幕一直处于高亮        //设置手机屏幕朝向,一共有7种        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);        //SCREEN_ORIENTATION_BEHIND: 继承Activity堆栈中当前Activity下面的那个Activity的方向        //SCREEN_ORIENTATION_LANDSCAPE: 横屏(风景照) ,显示时宽度大于高度         //SCREEN_ORIENTATION_PORTRAIT: 竖屏 (肖像照) , 显示时高度大于宽度         //SCREEN_ORIENTATION_SENSOR  由重力感应器来决定屏幕的朝向,它取决于用户如何持有设备,当设备被旋转时方向会随之在横屏与竖屏之间变化        //SCREEN_ORIENTATION_NOSENSOR: 忽略物理感应器——即显示方向与物理感应器无关,不管用户如何旋转设备显示方向都不会随着改变("unspecified"设置除外)        //SCREEN_ORIENTATION_UNSPECIFIED: 未指定,此为默认值,由Android系统自己选择适当的方向,选择策略视具体设备的配置情况而定,因此不同的设备会有不同的方向选择        //SCREEN_ORIENTATION_USER: 用户当前的首选方向        setContentView(R.layout.main);        back = (ImageView) findViewById(R.id.camera_back);        position = (ImageView) findViewById(R.id.camera_position);        surface = (SurfaceView) findViewById(R.id.camera_surface);        shutter = (ImageButton) findViewById(R.id.camera_shutter);        holder = surface.getHolder();//获得句柄        holder.addCallback(this);//添加回调        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//surfaceview不维护自己的缓冲区,等待屏幕渲染引擎将内容推送到用户面前        //设置监听        back.setOnClickListener(listener);        position.setOnClickListener(listener);        shutter.setOnClickListener(listener);    }    //响应点击事件    OnClickListener listener = new OnClickListener() {        @Override        public void onClick(View v) {            // TODO Auto-generated method stub            switch (v.getId()) {            case R.id.camera_back:                //返回                MyCameraActivity.this.finish();                break;            case R.id.camera_position:                //切换前后摄像头                int cameraCount = 0;                CameraInfo cameraInfo = new CameraInfo();                cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数                for(int i = 0; i < cameraCount; i   ) {                    Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息                    if(cameraPosition == 1) {                        //现在是后置,变更为前置                        if(cameraInfo.facing  == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表摄像头的方位,CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置                              camera.stopPreview();//停掉原来摄像头的预览                            camera.release();//释放资源                            camera = null;//取消原来摄像头                            camera = Camera.open(i);//打开当前选中的摄像头                            try {                                camera.setPreviewDisplay(holder);//通过surfaceview显示取景画面                            } catch (IOException e) {                                // TODO Auto-generated catch block                                e.printStackTrace();                            }                            camera.startPreview();//开始预览                            cameraPosition = 0;                            break;                        }                    } else {                        //现在是前置, 变更为后置                        if(cameraInfo.facing  == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表摄像头的方位,CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置                              camera.stopPreview();//停掉原来摄像头的预览                            camera.release();//释放资源                            camera = null;//取消原来摄像头                            camera = Camera.open(i);//打开当前选中的摄像头                            try {                                camera.setPreviewDisplay(holder);//通过surfaceview显示取景画面                            } catch (IOException e) {                                // TODO Auto-generated catch block                                e.printStackTrace();                            }                            camera.startPreview();//开始预览                            cameraPosition = 1;                            break;                        }                    }                }                break;            case R.id.camera_shutter:                //快门                camera.autoFocus(new AutoFocusCallback() {//自动对焦                    @Override                    public void onAutoFocus(boolean success, Camera camera) {                        // TODO Auto-generated method stub                        if(success) {                            //设置参数,并拍照                            Parameters params = camera.getParameters();                            params.setPictureFormat(PixelFormat.JPEG);//图片格式                            params.setPreviewSize(800, 480);//图片大小                            camera.setParameters(params);//将参数设置到我的camera                            camera.takePicture(null, null, jpeg);//将拍摄到的照片给自定义的对象                        }                    }                });                break;            }        }    };    /*surfaceHolder他是系统提供的一个用来设置surfaceView的一个对象,而它通过surfaceView.getHolder()这个方法来获得。     Camera提供一个setPreviewDisplay(SurfaceHolder)的方法来连接*/    //SurfaceHolder.Callback,这是个holder用来显示surfaceView 数据的接口,他必须实现以下3个方法    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {        // TODO Auto-generated method stub    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        // TODO Auto-generated method stub        //当surfaceview创建时开启相机        if(camera == null) {            camera = Camera.open();            try {                camera.setPreviewDisplay(holder);//通过surfaceview显示取景画面                camera.startPreview();//开始预览            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        // TODO Auto-generated method stub        //当surfaceview关闭时,关闭预览并释放资源        camera.stopPreview();        camera.release();        camera = null;        holder = null;        surface = null;    }    //创建jpeg图片回调数据对象    PictureCallback jpeg = new PictureCallback() {        @Override        public void onPictureTaken(byte[] data, Camera camera) {            // TODO Auto-generated method stub            try {                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);                //自定义文件保存路径  以拍摄时间区分命名                filepath = "/sdcard/Messages/MyPictures/"   new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())   ".jpg";                File file = new File(filepath);                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);//将图片压缩的流里面                bos.flush();// 刷新此缓冲区的输出流                bos.close();// 关闭此输出流并释放与此流有关的所有系统资源                camera.stopPreview();//关闭预览 处理数据                camera.startPreview();//数据处理完后继续开始预览                bitmap.recycle();//回收bitmap空间            } catch (Exception e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    };}
0 0
原创粉丝点击