在我们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() {@Overridepublic 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<Camera.Size> 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;elsethis.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()) {@Overridepublic 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 surfaceview 自定义相机 拍照(闪光灯、前后摄像头)相关推荐

  1. android自定义相机打开闪光灯,Android surfaceview 自定义相机 拍照(闪光灯、先后摄像头)...

    在咱们app中常常会调用相机进行拍照,而后把拍下来的图片保存在本地,再上传到服务端,网上有很多自定义的相机,也下载了很多,可是效果仍是不满意,因此决定自定义下,很少说了,直接上代码: public c ...

  2. Android关闭自定义相机拍照声音

    在自定义相机的代码中,调用 camera.takePicture(null,rawCallback,jpegCallback); 方法完成拍照时会发现无论系统的音量时震动.静音还是有声音都无法关闭自定 ...

  3. android自定义相机拍照

     Android中开发相机的两种方式: Android系统提供了两种使用手机相机资源实现拍摄功能的方法,一种是直接通过Intent调用系统相机组件,这种方法快速方便,适用于直接获得照片的场景,如上传相 ...

  4. android 自定义拍照模糊,Android自定义相机拍照模糊处理

    问题分析:随着用户对于拍照清晰度的需求,android手机对于摄像头也是一升再升,这就导致了作为android开发工程师对于兼容性维护的继续跟进以及问题处理. 针对于自定义相机拍照模糊的问题,经过几天 ...

  5. Android自定义相机拍照、图片裁剪的实现

    原文:Android自定义相机拍照.图片裁剪的实现 最近项目里面又要加一个拍照搜题的功能,也就是用户对着不会做的题目拍一张照片,将照片的文字使用ocr识别出来,再调用题库搜索接口搜索出来展示给用户,类 ...

  6. uni-app 自定义相机拍照录像,可设置分辨率、支持横竖屏(ios、android)

    插件市场:uni-app 自定义相机拍照录像,可设置分辨率.支持横竖屏(ios.android)

  7. Android Camera2自定义相机绿屏

    一.问题现象 在项目中使用Camera2自定义相机拍照,在其他手机上没有问题.在华为P40上.相机预览出现绿屏,绿屏如下所示 二.问题原因 预览设置高宽参数不符合相机高宽的话就会有绿条 原来的设置代码 ...

  8. android CameraX自定义相机使用

    android CameraX自定义相机使用 =<?xml version="1.0" encoding="utf-8"?> <android ...

  9. Android调用系统相机拍照并保存到指定位置

    Android调用系统相机拍照并保存到指定位置 @Click(R.id.btn_takePhoto)void onclick() {Intent intent = new Intent(MediaSt ...

最新文章

  1. 设置文件副本数_ElasticSearch平滑批量缩减索引分片数实践
  2. 利用卷积神经网络提取特征
  3. C语言基础之数据结构
  4. 华为4g模块 linux驱动程序,定制Android之4G-LTE模块驱动
  5. Bootstrap清除/清理浮动
  6. 暗黑系游戏_暗黑系冒险游戏,剧情引人入胜!
  7. 【iOS】Scale Fill、Aspect Fit 和 Aspect Fill 的区别(Content Mode)
  8. 【快捷键】—— 键盘篇
  9. 土豆 android 缓存路径,#土豆记事#教你开发Android App之 —— Hello Android
  10. Cufon中文字符无法识别的解决方案
  11. c语言程序开发分为四个步骤,c语言程序开发的步骤
  12. JavaWeb教程———Ajax
  13. 宏excel怎么计算机,excel宏的使用/EXCEL 如何关闭宏
  14. IE主页被2345(782782)篡改解决办法
  15. 怎样校验MD5码及sha1码数值(适用于Windows及Linux平台)
  16. 转码解密挖矿 显卡计算能力大对比
  17. Linux 命令 技能
  18. 黑客与画家——片段一
  19. java 消除png 锯齿_反转(移除)抗锯齿滤波器
  20. Android Studio 实现将视频资源嵌入APP中

热门文章

  1. Linux - 零拷贝技术
  2. C++仿照标准字符串类string,设计一个自己的字符串类String
  3. 360度全景拍摄,探索全景世界带你飞跃视野新高度
  4. linux pppd源码下载_Linux中的pppd
  5. 从零学会Photoshop经典教程300集
  6. 使用 Google Guava Striped 实现基于 Key 的并发锁
  7. 小米路由器刷Xiaomi Mi WiFi Mini openwrt
  8. DNS安全浅议、域名A记录(ANAME),MX记录,CNAME记录
  9. XML文件处理——XML文件简介
  10. 常见夸张标题,博人眼球