在咱们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;web

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自定义相机打开闪光灯,Android surfaceview 自定义相机 拍照(闪光灯、先后摄像头)...相关推荐

  1. android activity从新打开,【Android开发-8】生命周期,Activity中打开另一个Activity

    前言:生命中有不少人陪伴本身走过一辈子中的某段旅程,仅仅是有些人仅仅是某阶段出现,有些人却陪伴本身很是久.就像小学.中学.高中.大学,那些之前觉得会长久拥有的,当经历过天涯各地地忙碌于生活,或如意.或 ...

  2. android安装自动打开网页,Android调用系统自带浏览器打开网页的实现方法

    Android调用系统自带浏览器打开网页的实现方法 在Android中可以调用自带的浏览器,或者指定一个浏览器来打开一个链接.只需要传入一个uri,可以是链接地址. 启动android默认浏览器 在A ...

  3. android应用自动打开网页,Android 使用Scheme实现从网页启动APP

    通过使用Scheme,可以实现用手机的浏览器(内置或第三方)访问一个网页,启动自己的应用,或者在一个应用使用WebView.loadUrl()方法启动另外一个应用. 实现原理 首先我们来看一下网页跳转 ...

  4. Android关机充电打开log,Android关机log

    Android 版本:4.4 Linux 版本:3.10 查看关机log,分析启动原因,是否重启,正常关机. 关机原因位置:/proc/sys/kernel/boot_reason 重新启动: C:\ ...

  5. android点击打开drawer,android – 如何检测到DrawerLayout开始打开?

    有两种方法可以做到这一点: slideOffset从0变为1. 1表示完全打开,0 – 关闭. 一旦偏移从0变为0,就意味着它开始打开过程.就像是: mDrawerToggle = new Actio ...

  6. android pdf下载 打开方式,Android下载并打开pdf文件

    System.out.println("我点击了按钮"); String urlString = "http://public.dhe.ibm.com/common/ss ...

  7. android 4.0 打开gps,Android获取定位权限,手动打开GPS

    获取定位权限,并且在没有打开GPS的时候引导用户打开手机GPS定位. 超级简单的 private Button button; private int GPS_REQUEST_CODE = 1; @O ...

  8. android 自定义相机源码,Android 自定义相机及分析源码

    Android 自定义相机及分析源码 使用Android 系统相机的方法: 要想让应用有相机的action,咱们就必须在清单文件中做一些声明,好让系统知道,如下 action的作用就是声明action ...

  9. Android 解决通过自定义设置打开热点后手机搜索不到热点的问题。

    Android 解决通过自定义设置打开热点后手机搜索不到热点的问题. 参考文章: (1)Android 解决通过自定义设置打开热点后手机搜索不到热点的问题. (2)https://www.cnblog ...

  10. Android 调用系统打开相机,打开相册获取图片路径

    我们在开发中经常遇到一些功能需要调取系统相机拍照获取图片,或者有的时候直接打开图库获取图片,那我们怎么获取呢,今天分享下, 第一步,打开相机 public static final int CAMER ...

最新文章

  1. 再探C#类与结构体究竟谁快——考虑栈变量、栈分配、64位整数、密封类
  2. SAP QM 执行事务代码QA11 报错- Selected set code does not exist, or data entered is incomplete-
  3. 聊聊大麦网UWP版的首页顶部图片联动效果的实现方法
  4. Python之tkinter:动态演示调用python库的tkinter带你进入GUI世界(Find/undo事件)
  5. DP_字串匹配(HDU_1501)
  6. android qq 进程保活,Android保活从入门到放弃:乖乖引导用户加白名单吧(附7大机型加白示例)...
  7. mysql 学习笔记09字符串相关函数
  8. java文件日志功能_JAVA文件下载功能问题解决日志
  9. AutoCAD使用技巧
  10. Php.ini文件位置在哪里 Php.ini文件找不到
  11. 腾讯帮助警方破获 30+ 起吃鸡外挂案件;Java 领域的五大发展预测
  12. 创业公司做数据分析(一)开篇
  13. pq下垂控制单相逆变器matlab仿真,学习下垂控制的逆变器并联原理,如何实现仿真P1?-控制器/处理器-与非网...
  14. 教你识别思科交换机型号
  15. ThinkPad加装SSD固态硬盘/内存条 系统迁移
  16. Java动态追踪技术
  17. 解析儿童编程中的基本概念与目标
  18. Windows系统下结束卡死的应用程序
  19. Python 机器学习大作业 用knn算法对adult数据集进行50w年薪收入预测
  20. 装饰大楼,备用钥匙,IOIOI卡片占卜总结

热门文章

  1. 使用云监控实现GPU云服务器的GPU监控和报警(下)-云监控插件监控
  2. 若依RuoYi框架log图标与文字怎么改?
  3. cmd无法运行python_如何解决运行python指令提示不是内部或外部命令
  4. 代码随想录Day61
  5. Android 蓝牙 A2DP基础概念、A2DP音频流的建立及传输流程、A2DP播放暂停音乐命令交互过程分析 - 史上最全分析
  6. matlab_R2010b下载及安装文档和备用序列号
  7. C++学习笔记05--函数
  8. Xamarin.forms 学习笔记
  9. ProtoBuf 语法(一)
  10. API测试-接口测试基础(1)