Android surfaceview 自定义相机 拍照(闪光灯、前后摄像头)

在我们app中经常会调用相机进行拍照,然后把拍下来的图片保存在本地,再上传到服务端,网上有不少自定义的相机,也下载了不少,但是效果还是不满意,所以决定自定义下,不多说了,直接上代码:
public class CameraViews extends SurfaceView implements SurfaceHolder.Callback{
private String TAG=Camera.class.getName();
private Activity mActivity=null;
private Camera camera=null;
private SurfaceHolder holder=null;
/* 是否打开前置相机,true为前置,false为后置 */
private boolean mIsFrontCamera=false;
/是否开启闪光灯 默认关闭闪光灯/
private String isOpenFlashMode= Camera.Parameters.FLASH_MODE_OFF;
private int curRotation=0;
private CameraCallback mCallback=null;

public CameraViews(Context context){
    super(context);
    initSurface();
}

public CameraViews(Context context, AttributeSet attrs) {
    super(context, attrs);
    initSurface();
}

public void setCurActivity(Activity activity){
    this.mActivity=activity;
}

/**
 * @Description:  初始化surface
 * @Since:2015-8-11  
 * @Version:1.1.0
 */
private void initSurface(){
    holder =getHolder();//获得句柄
    holder.addCallback(this);//添加回调
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//surfaceview不维护自己的缓冲区,等待屏幕渲染引擎将内容推送到用户面前
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    try {
        if(camera==null){
            openCamera();
        }
        initCameraParams(mActivity);
        camera.setPreviewDisplay(getHolder());
        camera.startPreview();
    } catch (Exception e) {
        Toast.makeText(getContext(), "打开相机失败", Toast.LENGTH_SHORT).show();
        Log.e(TAG,e.getMessage());
    }
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
//try{
    //camera.stopPreview();
    //摄像头画面显示在Surface上
    //camera.setPreviewDisplay(holder);
    //initCameraParams(mActivity);
    //camera.startPreview();   
//}catch(IOException e) {
    // if (camera != null) camera.release();
    //camera = null;
//}

    //注意:这里不能进行重新初始化相机,然后在预览,不然进行横纵拍照,照出来的图片旋转的角度会对应不上,所以这里直接开启预览就好
    camera.startPreview();   
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    camera.stopPreview();
    camera.release();
    camera=null;
    holder=null;

}

@SuppressWarnings("unused")
private PictureCallback pictureCallback=new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        saveCameraImage(data, camera);
        //这句话也很重要,是将你拍照成功后,图片可以在相册中查看到。(只不过我把这句话封装到保存图片中,保存图片顺带加载到相册)。
        //MediaStore.Images.Media.insertImage(getContentResolver(), mBitmap, "", "");
        //重新打开预览图,进行下一次的拍照准备
        camera.startPreview();
    }
};
/**
 * @Description:设置相机预览 
 * @Since:2015-8-11  
 * @Version:1.1.0  
 * @param activity
 **/
public void setCameraPreView(){
    if(camera!=null){
        camera.stopPreview();
        initCameraParams(mActivity);
        try {
            camera.setPreviewDisplay(getHolder());
            camera.startPreview();
        } catch (IOException e) {
            Log.e(">>>>>","相机转换失败!"+e.getMessage());
        }
    }else{
        Log.e(">>>>>","相机初始化失败!");
    }
}

/**
 * @Description:保存拍照的图片
 * @Since:2015-8-11  
 * @Version:1.1.0  
 * @param data
 * @param camera
 */
private void saveCameraImage(byte[] data, Camera camera) {
    if(data==null){
        Log.e(TAG, "获取图片流失败,拍照失败,请重试!");
        return;
    }
    if(isFrontCamera()){
        if(curRotation==90){
            curRotation=270;
        }else if(curRotation==270){
            curRotation=90;
        }
    }
    Bitmap thumbBM=null;
    thumbBM=BitmapUtils.getInstance().save(mActivity,data,curRotation);
    mCallback.onCameraCallback(thumbBM);
    thumbBM=null;

}

/**
 * @Description:设置相机参数
 * @Since:2015-8-11  
 * @Version:1.1.0
 */
public void initCameraParams(Activity activity){
    Camera.Parameters parameters = camera.getParameters();
    // 选择合适的预览尺寸   
    List sizeList = parameters.getSupportedPreviewSizes();
    if (sizeList.size()>0) {
        Size cameraSize=sizeList.get(0);
        //预览图片大小
        parameters.setPreviewSize(cameraSize.width, cameraSize.height);
    }

    //设置生成的图片大小
    sizeList = parameters.getSupportedPictureSizes();
    if (sizeList.size()>0) {
        Size cameraSize=sizeList.get(0);
        for (Size size : sizeList) {
            //小于100W像素
            if (size.width*size.height<100*10000) {
                cameraSize=size;
                break;
            }
        }
        parameters.setPictureSize(cameraSize.width, cameraSize.height);
    }
    //设置图片格式
    parameters.setPictureFormat(ImageFormat.JPEG);       
    parameters.setJpegQuality(100);
    parameters.setJpegThumbnailQuality(100);
    //自动聚焦模式
    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
    parameters.setFlashMode(getIsOpenFlashMode());
    //curRotation=getPreviewDegree();
    screenDirectionListener();
    //Log.e(">>>>>","curRotation:"+curRotation);
    //parameters.setRotation(curRotation);//生成的图片转90°
    //camera.setDisplayOrientation(curRotation);//预览转90°预览图片旋转90°
    //camera.setDisplayOrientation(getPreviewDegree());//预览旋转90°
    camera.setDisplayOrientation(90);
    camera.setParameters(parameters);
}
public String getIsOpenFlashMode() {
    return isOpenFlashMode;
}

/**
 * @Description:  设置开启闪光灯(重新预览)
 * @Since:2015-8-12  
 * @Version:1.1.0  
 * @param mIsOpenFlashMode
 */
public void setIsOpenFlashMode(boolean mIsOpenFlashMode) {
    if(mIsOpenFlashMode)
        this.isOpenFlashMode = Camera.Parameters.FLASH_MODE_ON;
    else
        this.isOpenFlashMode =  Camera.Parameters.FLASH_MODE_OFF;;
    setCameraPreView();//重新预览相机
}

/**  
 *   根据当前照相机状态(前置或后置),打开对应相机
 */
private boolean openCamera()  {
    if (camera != null) {
        camera.stopPreview();
        camera.release();
        camera = null;
    }

    if(mIsFrontCamera){
        Camera.CameraInfo cameraInfo=new CameraInfo();
        for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if(cameraInfo.facing==Camera.CameraInfo.CAMERA_FACING_FRONT){
                try {
                    camera=Camera.open(i);
                } catch (Exception e) {
                    camera =null;
                    return false;
                }
            }
        }
    }else {
        try {
            camera=Camera.open();
        } catch (Exception e) {
            camera =null;
            return false;
        }
    }
    return true;
}

/**
 * @Description:获取相机摄像头个数  
 * @Since:2015-8-11  
 * @Version:1.1.0  
 * @return
 */
public int getCameraCount(){
    return Camera.getNumberOfCameras();//得到摄像头的个数
}

private boolean isFrontCamera(){
    return mIsFrontCamera;
}

/**
 * @Description:转换前置和后置照相机
 * @Since:2015-8-11  
 * @Version:1.1.0  
 * @return
 */
public boolean switchCamera(){
    mIsFrontCamera=!mIsFrontCamera;
    openCamera();
    if(camera!=null){
        initCameraParams(mActivity);
        //updateCameraOrientation();
        try {
            camera.setPreviewDisplay(getHolder());
            camera.startPreview();
        } catch (IOException e) {
            Log.e(">>>>>","相机转换失败!"+e.getMessage());
        }
    }
    return mIsFrontCamera;
}

/**
 * @Description:  拍照
 * @Since:2015-8-31  
 * @Version:1.1.0  
 * @param mCameraCallback
 */
public void takePhoto(CameraCallback mCameraCallback){
    try {
        initSurface();
        initCameraParams(mActivity);
        camera.takePicture(null, null, pictureCallback);//将拍摄到的照片给自定义的对象
        this.mCallback=mCameraCallback;
    } catch (Exception e) {
        Toast.makeText(mActivity,"初始化相机失败!",Toast.LENGTH_SHORT).show();
    }
}
public interface CameraCallback{
    void onCameraCallback(Bitmap bitmap);
}
/**
 * @Description:  监听屏幕的旋转方向
 * @Since:2015-8-12  
 * @Version:1.1.0
 */
private void screenDirectionListener(){
    OrientationEventListener mOrEventListener =new OrientationEventListener(getContext()) {

        @Override
        public void onOrientationChanged(int rotation) {
            //getScreenDirect();
             if (((rotation >= 0) && (rotation <= 45)) || (rotation >= 315)||((rotation>=135)&&(rotation<=225))){////portrait
             } else if (((rotation > 45) && (rotation < 135))||((rotation>225)&&(rotation<315))) {//landscape
             }
            if (((rotation >= 0) && (rotation <= 45)) || (rotation > 315)){//纵屏向上
                rotation=90;
            }else if ((rotation > 45) && (rotation <= 135))  {//横屏向右
                rotation=180;
            }
            else if ((rotation > 135) && (rotation <= 225)) {//纵屏向下
                rotation=270;
            } 
            else if((rotation > 225) && (rotation <= 315)) { //横屏向左
                rotation=0;
            }else {
                rotation=0;
            }
            curRotation=rotation;
        }
    };
    mOrEventListener.enable();
}

你可能感兴趣的:(android,拍照)