android 自定义相机Camera

转载请标明来自:http://blog.csdn.net/qq_38416326/article/details/70809754

项目中,有时系统的相机不能满足我们的需求,例如:实现美图,这样就需要我们进行自定义相机,满足我们的特殊需求。Android给我们提供了Camera API,可以进行相机的私人订制。在Android5以后有提供了Camera2 API,废除了Camera API。但Camera仍旧可以使用,Camera2使用起来感觉比Camera要复杂些,Camera2功能要强于Camera,也是google提倡使用的。Camera已经基本可以满足需求了,今天我们就要看一下Camera的使用,下一篇我们会讲到Camera2的使用。

一、获取Camera

camera=Camera.open();
二、与 SurfaceView进行关联(SurfaceView进行图像绘制

sfh=sfv.getHolder();
sfh.addCallback(new SurfaceHolder.Callback() {
    //创建
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        //开始进行图片的预览
        startPreview();
    }
    //改变
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        //停止旧的预览,开启新的预览
        camera.stopPreview();
        startPreview();
    }
    //释放
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        //停止预览,释放资源
        stopCamera();
    }
});
三、进行预览

/**
 * 相机预览*/
private void startPreview(){
    try {
        //相机与SurfaceView进行绑定
        camera.setPreviewDisplay(sfh);
        //预览的图片旋转
        camera.setDisplayOrientation(90);
        camera.startPreview();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

四、拍照

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        //设置相机的各种参数
        Camera.Parameters parameters=camera.getParameters();
        //对焦的方式
        parameters.setFocusMode(Camera.Parameters.ANTIBANDING_AUTO);
        //照片的类型
        parameters.setPictureFormat(ImageFormat.JPEG);
        //对焦监听
        camera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                //对焦成功
                if(success){
                    camera.takePicture(null,null,cameraCallBack);
                }else{
                    Toast.makeText(MainActivity.this,"对焦失败!",Toast.LENGTH_SHORT).show();
                }
            }
        });


    }
});
五、处理拍照图片,进行存到本地相册,和本页面预览
/**
 * 拍照成功回调函数*/
private Camera.PictureCallback cameraCallBack=new Camera.PictureCallback() {
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        startPreview();

        //先验证手机是否有sdcard
        String status= Environment.getExternalStorageState();
        if(!status.equals(Environment.MEDIA_MOUNTED))
        {
            Toast.makeText(getApplicationContext(),"你的sd卡不可用。",Toast.LENGTH_SHORT).show();
            return;
        }
        //大部分手机拍照都是存到这个路径
        String filePath=Environment.getExternalStorageDirectory().getPath()+"/DCIM/Camera/";
        String picturePath=System.currentTimeMillis()+".jpg";
        File file=new File(filePath,picturePath);
        try{
            //存到本地相册
            FileOutputStream fileOutputStream=new FileOutputStream(file);
            fileOutputStream.write(data);
            fileOutputStream.close();

            //显示图片
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 2;
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
            iv.setImageBitmap(bitmap);
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }

    }
};

六、资源的释放

/**
 * 停止拍照释放资源*/
private void stopCamera(){
    if(camera!=null){
        camera.stopPreview();
        camera.release();
        camera=null;
    }

}

放上activity代码:

package com.sunshanglei.camera.customcamera;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * use 自定义相机Camera
 * author 孙尚磊
 * create time 2017-4-26
 */
public class MainActivity extends AppCompatActivity {

    private SurfaceView sfv;
    private ImageView iv;
    private Button btn;
    private Camera camera=null;
    private SurfaceHolder sfh;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sfv= (SurfaceView) findViewById(R.id.sfv);
        iv= (ImageView) findViewById(R.id.iv);
        btn= (Button) findViewById(R.id.btn);
        camera=Camera.open();
        sfh=sfv.getHolder();
        sfh.addCallback(new SurfaceHolder.Callback() {
            //创建
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                //开始进行图片的预览
                startPreview();
            }
            //改变
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                //停止旧的预览,开启新的预览
                camera.stopPreview();
                startPreview();
            }
            //释放
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                //停止预览,释放资源
                stopCamera();
            }
        });

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //设置相机的各种参数
                Camera.Parameters parameters=camera.getParameters();
                //对焦的方式
                parameters.setFocusMode(Camera.Parameters.ANTIBANDING_AUTO);
                //照片的类型
                parameters.setPictureFormat(ImageFormat.JPEG);
                //对焦监听
                camera.autoFocus(new Camera.AutoFocusCallback() {
                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        //对焦成功
                        if(success){
                            camera.takePicture(null,null,cameraCallBack);
                        }else{
                            Toast.makeText(MainActivity.this,"对焦失败!",Toast.LENGTH_SHORT).show();
                        }
                    }
                });


            }
        });
    }

    /**
     * 拍照成功回调函数*/
    private Camera.PictureCallback cameraCallBack=new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            startPreview();

            //先验证手机是否有sdcard
            String status= Environment.getExternalStorageState();
            if(!status.equals(Environment.MEDIA_MOUNTED))
            {
                Toast.makeText(getApplicationContext(),"你的sd卡不可用。",Toast.LENGTH_SHORT).show();
                return;
            }
            //大部分手机拍照都是存到这个路径
            String filePath=Environment.getExternalStorageDirectory().getPath()+"/DCIM/Camera/";
            String picturePath=System.currentTimeMillis()+".jpg";
            File file=new File(filePath,picturePath);
            try{
                //存到本地相册
                FileOutputStream fileOutputStream=new FileOutputStream(file);
                fileOutputStream.write(data);
                fileOutputStream.close();

                //显示图片
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 2;
                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
                iv.setImageBitmap(bitmap);
            }catch (FileNotFoundException e){
                e.printStackTrace();
            }catch (IOException e){
                e.printStackTrace();
            }

        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        if(camera==null){
            camera=Camera.open();
            if(sfh!=null){
                startPreview();
            }
        }

    }

    @Override
    protected void onPause() {
        super.onPause();
        if(camera!=null) {
            stopCamera();
        }
    }

    /**
     * 相机预览*/
    private void startPreview(){
        try {
            //相机与SurfaceView进行绑定
            camera.setPreviewDisplay(sfh);
            //预览的图片旋转
            camera.setDisplayOrientation(90);
            camera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 停止拍照释放资源*/
    private void stopCamera(){
        if(camera!=null){
            camera.stopPreview();
            camera.release();
            camera=null;
        }

    }
}

布局xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <SurfaceView
        android:id="@+id/sfv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/ll_bottom"/>
    <RelativeLayout
        android:id="@+id/ll_bottom"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:layout_alignParentBottom="true">

        <ImageView
            android:id="@+id/iv"
            android:layout_width="wrap_content"
            android:layout_height="70dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:src="@mipmap/ic_launcher"/>
        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="10dp"
            android:text="拍照"/>
    </RelativeLayout>
</RelativeLayout>

最后不要忘了放上权限:

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

效果图:


apk下载:http://download.csdn.net/detail/qq_38416326/9827219

源码下载:http://download.csdn.net/detail/qq_38416326/9827225

https://github.com/sunshanglei/CustomCamera






猜你喜欢

转载自blog.csdn.net/qq_38416326/article/details/70809754