自定义相机,使用前置摄像头实现自拍

来源:互联网 发布:win10输入法切换软件 编辑:程序博客网 时间:2024/04/19 13:28

通过Camera.open()获取相机,实现自定义自拍功能。

demo比较简单,直接上代码:

Activity

public class MainActivity extends AppCompatActivity {    SurfaceView sView;    SurfaceHolder surfaceHodler;    int screenWidth, screenHeight;    // 定义系统所用的照相机    Camera camera;    // 是否存在预览中    boolean isPreview = false;    private String filepath = "";//照片保存路径    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // 获取窗口管理器        WindowManager wm = getWindowManager();        Display display = wm.getDefaultDisplay();        DisplayMetrics metrics = new DisplayMetrics();        // 获取屏幕的宽和高        display.getMetrics(metrics);        screenWidth = metrics.widthPixels;        screenHeight = metrics.heightPixels;        sView = (SurfaceView) findViewById(R.id.sView);        // 设置surface不需要自己的维护缓存区        sView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);        // 获得SurfaceView的SurfaceHolder        surfaceHodler = sView.getHolder();        // 为srfaceHolder添加一个回调监听器        surfaceHodler.addCallback(new SurfaceHolder.Callback() {            @Override            public void surfaceDestroyed(SurfaceHolder arg0) {                // 如果camera不为null,释放摄像头                System.out.println("释放摄像头");                if (camera != null) {                    if (isPreview)                        camera.stopPreview();                    camera.release();                    camera = null;                    isPreview = false;                }            }            @Override            public void surfaceCreated(SurfaceHolder arg0) {                System.out.println("打开摄像头");                // 打开摄像头                initCamera();            }            @Override            public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,                                       int arg3) {                System.out.println("摄像头改变");            }        });    }    public void capture(View source) {        sView.setVisibility(View.VISIBLE);    }    private void initCamera() {        if (!isPreview) {            // 此处默认打开后置摄像头            // 通过传入参数可以打开前置摄像头            camera = openFrontFacingCameraGingerbread();        }        if (!isPreview && camera != null) {            Camera.Parameters parameters = camera.getParameters();            // 设置预览照片的大小            parameters.setPreviewSize(screenWidth, screenHeight);            // 设置预览照片时每秒显示多少帧的最小值和最大值            parameters.setPreviewFpsRange(4, 10);            // 设置照片的格式            parameters.setPictureFormat(ImageFormat.JPEG);            parameters.setPreviewSize(800, 480);//图片大小            // 设置JPG照片的质量            parameters.set("jpeg-quality", 100);            // 设置照片的大小            parameters.setPictureSize(screenWidth, screenHeight);            // 通过SurfaceView显示取景画面            try {                camera.setPreviewDisplay(surfaceHodler);                // 系统相机默认是横屏的,我们要旋转90°                camera.setDisplayOrientation(90);            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            // 开始预览            camera.startPreview();            isPreview = true;            new Handler().postDelayed(new Runnable() {                @Override                public void run() {                    if (camera != null) {                        System.out.println("控制摄像头自动对焦后才拍摄");                        // 控制摄像头自动对焦后才拍摄                        //camera.autoFocus(autoFocusCallback);                        //关闭声音                        setCameraSound(true);                        camera.takePicture(new Camera.ShutterCallback() {                            @Override                            public void onShutter() {                                // 按下快门瞬间会执行此处代码                            }                        }, new Camera.PictureCallback() {                            @Override                            public void onPictureTaken(byte[] arg0, Camera arg1) {                                // 此处代码可以决定是否需要保存原始照片信息                            }                        }, jpeg);                    }                }            }, 1000);        }    }    private Camera openFrontFacingCameraGingerbread() {        int cameraCount = 0;        Camera cam = null;        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();        cameraCount = Camera.getNumberOfCameras();        System.out.println("cameraCount = "+cameraCount);        for (int camIdx = 0; camIdx < cameraCount; camIdx++) {            Camera.getCameraInfo(camIdx, cameraInfo);            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {                try {                    cam = Camera.open(camIdx);                } catch (RuntimeException e) {                    Log.e("", "Camera failed to open: " + e.getLocalizedMessage());                }            }        }        System.out.println("获取摄像头");        if (cam == null)            System.out.println("摄像头获取失败");        return cam;    }    Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {        @Override        public void onAutoFocus(boolean arg0, Camera arg1) {            if (arg0) {                //关闭声音                setCameraSound(true);                // takePicture()方法需要传入三个监听参数                // 第一个监听器;当用户按下快门时激发该监听器                // 第二个监听器;当相机获取原始照片时激发该监听器                // 第三个监听器;当相机获取JPG照片时激发该监听器                System.out.println("拍照");                camera.takePicture(new Camera.ShutterCallback() {                    @Override                    public void onShutter() {                        // 按下快门瞬间会执行此处代码                    }                }, new Camera.PictureCallback() {                    @Override                    public void onPictureTaken(byte[] arg0, Camera arg1) {                        // 此处代码可以决定是否需要保存原始照片信息                    }                }, jpeg);                new Handler().postDelayed(new Runnable() {                    @Override                    public void run() {                      //  sView.setVisibility(View.GONE);                        //                    }                }, 1000);            } else {                System.out.println("对焦失败,不拍照");            }        }    };    //创建jpeg图片回调数据对象    Camera.PictureCallback jpeg = new Camera.PictureCallback() {        @Override        public void onPictureTaken(byte[] data, Camera camera) {            // TODO Auto-generated method stub            try {                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);                // 创建一个位于SD卡上的文件                File file = new File(Environment.getExternalStorageDirectory() + File.separator + "aaa");                if (!file.exists()) {                    file.mkdir();                }                file = new File(file, System.currentTimeMillis() + ".jpg");                FileOutputStream fileOutStream = null;                try {                    fileOutStream = new FileOutputStream(file);                    //把位图输出到指定的文件中                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutStream);                    fileOutStream.close();                } catch (IOException io) {                    io.printStackTrace();                }                camera.stopPreview();//关闭预览 处理数据                camera.startPreview();//数据处理完后继续开始预览                bitmap.recycle();//回收bitmap空间                isPreview = true;                //关闭预览框,回复声音                sView.setVisibility(View.GONE);                setCameraSound(false);            } catch (Exception e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    };    private void setCameraSound(final boolean isSound) {        new Thread(                new Runnable() {                    @Override                    public void run() {                        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);                        audioManager.setStreamMute(AudioManager.STREAM_SYSTEM, isSound);                    }                }        ).start();    }}

XML

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.jin.activity.MainActivity">    <SurfaceView        android:id="@+id/sView"        android:layout_width="80dp"        android:layout_height="100dp"        android:layout_alignParentRight="true"        android:visibility="gone"></SurfaceView>    <Button        android:id="@+id/take"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:onClick="capture"        android:text="开门"></Button></RelativeLayout>

注:
经过测试发现7.0以下手机没问题,而7.0系统手机在Camera.open()出现Camera failed to open: Fail to connect to camera service,就是获取不到相机服务无法打开相机,需要手动在手机设置里面打开相机权限,即可正常使用。因此可以加一个判断:

//判断系统版本大于23,即247.0)和以上版本提示打开权限        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {        }
阅读全文
0 0
原创粉丝点击