好久不写博客了,代码写了不少,但大多数都是拿来主义,要不是网上,要不就是自己曾经的代码拼装。

新工作是搞Android开发的,近期任务要求我封装一个Carmera类,自己也认为还是封装以后方便使用,弄了半天写好一个,能够调用手机前置后置摄像头进行拍照摄像,并能够依据设置相机各种參数,进行保存。发到这里分享下。

package com.hourglass.camerademo;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List; import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.Size;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView; /**
* 拍照录像封装类
*
* @author Hourglass 2014年4月21日 Q331956750
* @version 1.2
*/
public class MediaCamera {
private static int cameraPosition = Camera.CameraInfo.CAMERA_FACING_FRONT; private static String tag = "MediaCamera---------------------"; private static int back_PictureWidth;
private static int back_PictureHeight;
private static int back_PreviewWidth;
private static int back_PreviewHeight;
private static int back_degrees;
private static String back_FocusMode;
private static int back_pixel_format; private static int front_PictureWidth;
private static int front_PictureHeight;
private static int front_PreviewWidth;
private static int front_PreviewHeight;
private static int front_degrees;
private static String front_FocusMode;
private static int front_pixel_format; private static int back_output_format;
private static int back_video_encoder;
private static int back_Video_width;
private static int back_Video_height;
private static int back_Video_rate; private static int front_output_format;
private static int front_video_encoder;
private static int front_Video_width;
private static int front_Video_height;
private static int front_Video_rate; private Bitmap mBitmap = null; private MediaRecorder mediarecorder;
public boolean isRecording; private static String DefaultImagePath = Environment
.getExternalStorageDirectory().getPath() + "/Pictures/";
private static String DefaultImageName = "Image";
private static String DefaultVedioPath = Environment
.getExternalStorageDirectory().getPath() + "/Pictures/";
private static String DefaultVedioName = "Video"; private Camera camera = null;
private SurfaceView surfaceView = null;
private SurfaceHolder surfaceHolder = null; public MediaCamera(SurfaceView surfaceView) {
super();
this.surfaceView = surfaceView;
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(surfaceHolderCallback);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
} /******************************* 静态检測类 ********************************************/
/**
* 检測设备是否有摄像头
*
* @param context
* 执行上下文
* @return 若有摄像头 返回true 若无返回false
*/
public static boolean checkCameraHardware(Context context) {
return context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA) ? true : false;
} /**
* 检測设备SD卡状态
*
* @return 正常返回true 不正常返回false
*/
public static boolean checkDeviceSDEnable() {
return android.os.Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED) ? true : false;
} /**
* 检測设备SD卡剩余空间
*
* @return 单位MB
*/
public static long getSDFreeSize() {
// 取得SD卡文件路径
File path = Environment.getExternalStorageDirectory();
StatFs sf = new StatFs(path.getPath());
// 获取单个数据块的大小(Byte)
long blockSize = sf.getBlockSize();
// 空暇的数据块的数量
long freeBlocks = sf.getAvailableBlocks();
// 返回SD卡空暇大小
// return freeBlocks * blockSize; //单位Byte
// return (freeBlocks * blockSize)/1024; //单位KB
return (freeBlocks * blockSize) / 1024 / 1024; // 单位MB
} /**
* 检測设备SD卡总容量
*
* @return 单位MB
*/
public static long getSDAllSize() {
// 取得SD卡文件路径
File path = Environment.getExternalStorageDirectory();
StatFs sf = new StatFs(path.getPath());
// 获取单个数据块的大小(Byte)
long blockSize = sf.getBlockSize();
// 获取全部数据块数
long allBlocks = sf.getBlockCount();
// 返回SD卡大小
// return allBlocks * blockSize; //单位Byte
// return (allBlocks * blockSize)/1024; //单位KB
return (allBlocks * blockSize) / 1024 / 1024; // 单位MB
} /******************************* 静态检測类结束 ********************************************/
/**
* 打开或切换前后摄像头
*/
public void OpenCamera() {
int cameraCount = 0;
CameraInfo cameraInfo = new CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for (int i = 0; i < cameraCount; i++) {
Camera.getCameraInfo(i, cameraInfo);
releaseCamera();
if (cameraPosition == Camera.CameraInfo.CAMERA_FACING_FRONT) {
// 如今是后置,变更为前置
cameraPosition = Camera.CameraInfo.CAMERA_FACING_BACK;
try {
camera = Camera.open(cameraPosition);
camera.setPreviewDisplay(surfaceHolder);
} catch (Exception e) {
Log.d(tag, "前置相机无法打开或正在被占用");
}
try {
setCameraParameters(camera, 1);
} catch (Exception e) {
e.printStackTrace();
Log.d(tag, "前置相机无法设置參数");
}
camera.startPreview();
break;
} else {
// 如今是前置, 变更为后置
cameraPosition = Camera.CameraInfo.CAMERA_FACING_FRONT;
try {
camera = Camera.open(cameraPosition);
camera.setPreviewDisplay(surfaceHolder);
} catch (Exception e) {
Log.d(tag, "后置相机无法打开或正在被占用");
}
try {
setCameraParameters(camera, 0);
} catch (Exception e) {
e.printStackTrace();
Log.d(tag, "前置相机无法设置參数");
}
camera.startPreview();
break;
}
}
} /**
* Camera拍照
*
* @param Suffix
* 生成JPEG 0 生成PNG 1
*/
public void takePhoto(int Suffix) {
if (camera != null) {
try {
if (Suffix == 0)
camera.takePicture(null, null, JpegCallback);
else
camera.takePicture(null, null, PngCallback);
} catch (Exception e) {
e.printStackTrace();
}
}
camera.startPreview();
} /**
* JPEG回调方法
* **/
private PictureCallback JpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
if (null != data) {
mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length); }
Matrix matrix = new Matrix();
matrix.postRotate((float) 0.0);
Bitmap rotaBitmap = Bitmap.createBitmap(mBitmap, 0, 0,
mBitmap.getWidth(), mBitmap.getHeight(), matrix, false);
if (null != rotaBitmap) {
savePicture(rotaBitmap, DefaultImagePath,
Bitmap.CompressFormat.JPEG, DefaultImageName, ".jpeg");
}
}
};
/**
* Png回调方法
* **/
private PictureCallback PngCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
if (null != data) {
mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
}
Matrix matrix = new Matrix();
matrix.postRotate((float) 0.0);
Bitmap rotaBitmap = Bitmap.createBitmap(mBitmap, 0, 0,
mBitmap.getWidth(), mBitmap.getHeight(), matrix, false);
if (null != rotaBitmap) {
savePicture(rotaBitmap, DefaultImagePath,
Bitmap.CompressFormat.PNG, DefaultImageName, ".png");
}
}
}; /**
* 保存Bitmap
*
* @param bitmap
* @param savePath
* @param format
* 编码格式
* @param filename
* 文件名称 Null则依照当前毫秒命名
* @param suffix
* 后缀名
*/
private void savePicture(Bitmap bitmap, String savePath,
CompressFormat format, String filename, String suffix) {
File folder = new File(savePath);
if (!folder.exists()) {
folder.mkdir();
}
String jpegName;
if (filename == null || filename.length() == 0)
jpegName = savePath + System.currentTimeMillis() + suffix;
else {
jpegName = savePath + filename + suffix;
}
try {
FileOutputStream fout = new FileOutputStream(jpegName);
BufferedOutputStream bos = new BufferedOutputStream(fout); bitmap.compress(format, 100, bos);
bos.flush();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
} private void setCameraParameters(Camera myCamera, int type) {
if (null != myCamera) {
Camera.Parameters myParam = myCamera.getParameters(); if (type == 1) {
myParam.setPictureFormat(back_pixel_format);
myParam.setPictureSize(back_PictureWidth,
back_PictureHeight);
myParam.setPreviewSize(back_PreviewWidth,
back_PreviewHeight);
myCamera.setDisplayOrientation(back_degrees);
myParam.setFocusMode(back_FocusMode);
} else {
myParam.setPictureFormat(front_pixel_format);
myParam.setPictureSize(front_PictureWidth, front_PictureHeight);
myParam.setPreviewSize(front_PreviewWidth, front_PreviewHeight);
myCamera.setDisplayOrientation(front_degrees);
myParam.setFocusMode(front_FocusMode);
} myCamera.setParameters(myParam);
}
} private void setRecordParameters(int type) {
mediarecorder.setCamera(camera);
mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
if (type == 0) {
mediarecorder.setOutputFormat(back_output_format);
mediarecorder.setVideoEncoder(back_video_encoder);
mediarecorder.setVideoFrameRate(back_Video_rate);
mediarecorder.setVideoSize(back_Video_width, back_Video_height);
} else {
mediarecorder.setOutputFormat(front_output_format);
mediarecorder.setVideoEncoder(front_video_encoder);
mediarecorder.setVideoFrameRate(front_Video_rate);
mediarecorder.setVideoSize(front_Video_width, front_Video_height);
}
mediarecorder.setPreviewDisplay(surfaceHolder.getSurface());
if (front_output_format == MediaRecorder.OutputFormat.MPEG_4)
mediarecorder.setOutputFile(DefaultVedioPath + DefaultVedioName
+ ".mp4");
else if (front_output_format == MediaRecorder.OutputFormat.THREE_GPP)
mediarecorder.setOutputFile(DefaultVedioPath + DefaultVedioName
+ ".3gp");
else
new Exception("不支持的生成视频格式");
} /**
* 初始化相机參数方法(后置)
*
* @param myCamera
* Camera实例
* @param pixel_format
* 设置拍照后存储的图片格式
* @param PictureWidth
* 存储的图片像素X
* @param PictureHeight
* 存储的图片像素Y
* @param PreviewWidth
* 显示宽度X
* @param PreviewHeight
* 显示高度Y
* @param degrees
* 旋转角度
* @param FocusMode
* 调焦方式
*/
public static void initCameraParameters_back(int pixel_format,
int PictureWidth, int PictureHeight, int PreviewWidth,
int PreviewHeight, int degrees, String FocusMode) {
MediaCamera.back_pixel_format = pixel_format;
MediaCamera.back_PictureWidth = PictureWidth;
MediaCamera.back_PictureHeight = PictureHeight;
MediaCamera.back_PreviewWidth = PreviewWidth;
MediaCamera.back_PreviewHeight = PreviewHeight;
MediaCamera.back_degrees = degrees;
MediaCamera.back_FocusMode = FocusMode;
} /**
* 初始化相机參数方法(前置)
*
* @param myCamera
* Camera实例
* @param pixel_format
* 设置拍照后存储的图片格式
* @param PictureWidth
* 存储的图片像素X
* @param PictureHeight
* 存储的图片像素Y
* @param PreviewWidth
* 显示宽度X
* @param PreviewHeight
* 显示高度Y
* @param degrees
* 旋转角度
* @param FocusMode
* 调焦方式
*/
public static void initCameraParameters_front(int pixel_format,
int PictureWidth, int PictureHeight, int PreviewWidth,
int PreviewHeight, int degrees, String FocusMode) {
MediaCamera.front_pixel_format = pixel_format;
MediaCamera.front_PictureWidth = PictureWidth;
MediaCamera.front_PictureHeight = PictureHeight;
MediaCamera.front_PreviewWidth = PreviewWidth;
MediaCamera.front_PreviewHeight = PreviewHeight;
MediaCamera.front_degrees = degrees;
MediaCamera.front_FocusMode = FocusMode;
} /**
* 初始化相机摄像參数方法(后置)
*
* @param surfaceView
* @param output_format
* 视频的封装格式MediaRecorder.OutputFormat THREE_GPP为3gp.MPEG_4为mp4
* @param video_encoder
* 视频编码MediaRecorder.VideoEncoder h263 h264
* @param width
* 分辨率width
* @param height
* 分辨率height
* @param rate
* 视频的码率
* @param path
* 文件输出的路径
*/
public static void initRecordParameters_back(int output_format,
int video_encoder, int Video_width, int Video_height, int Video_rate) {
MediaCamera.back_output_format = output_format;
MediaCamera.back_Video_width = Video_width;
MediaCamera.back_Video_height = Video_height;
MediaCamera.back_output_format = output_format;
MediaCamera.back_Video_rate = Video_rate; } /**
* 初始化相机摄像參数方法(前置)
*
* @param surfaceView
* @param back_output_format
* 视频的封装格式MediaRecorder.OutputFormat THREE_GPP为3gp.MPEG_4为mp4
* @param back_video_encoder
* 视频编码MediaRecorder.VideoEncoder h263 h264
* @param width
* 分辨率width
* @param height
* 分辨率height
* @param rate
* 视频的码率
* @param path
* 文件输出的路径
*/
public static void initRecordParameters_front(int output_format,
int video_encoder, int Video_width, int Video_height, int Video_rate) {
MediaCamera.front_output_format = output_format;
MediaCamera.front_Video_width = Video_width;
MediaCamera.front_Video_height = Video_height;
MediaCamera.front_output_format = output_format;
MediaCamera.front_Video_rate = Video_rate; } /**
* 设置相片保存路径
*
* @param defaultFilePath
* 路径 example: "/mnt/sdcard/Pictures/"
*/
public static void setDefaultImagePath(String defaultFilePath) {
DefaultImagePath = defaultFilePath;
} /**
* 设置相片名称
*
* @param defaultFilePath
*/
public static void setDefaultImageName(String defaultFileName) {
DefaultImageName = defaultFileName;
} /**
* 设置视频保存路径
*
* @param defaultFilePath
* 路径 example: "/mnt/sdcard/Pictures/"
*/
public static void setDefaultVedioPath(String defaultFilePath) {
DefaultVedioPath = defaultFilePath;
} /**
* 设置视频名称
*
* @param defaultFilePath
*/
public static void setDefaultVedioName(String defaultFileName) {
DefaultVedioName = defaultFileName;
} /**
* 開始录像方法
* */
public void startRecording() {
camera.unlock();
mediarecorder = new MediaRecorder();
setRecordParameters(cameraPosition);
try {
mediarecorder.prepare();
mediarecorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
isRecording = true; } /**
* 停止录像方法
* */
public void stopRecording() {
if (mediarecorder != null) {
mediarecorder.stop();
mediarecorder.release();
mediarecorder = null;
}
} /**
* SurfaceHolderCallback 重写
* **/
Callback surfaceHolderCallback = new Callback() { @Override
public void surfaceDestroyed(SurfaceHolder arg0) {
surfaceView = null;
surfaceHolder = null;
releaseCamera();
} @Override
public void surfaceCreated(SurfaceHolder arg0) {
OpenCamera();
camera.startPreview();
} @Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
int arg3) {
// setCameraParameters(camera);
camera.startPreview(); }
}; private void releaseCamera() {
if (camera != null) {
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
camera = null;
}
}
}

使用时依照下面步骤调用就能够了:

1.Activity中布局SurfaceView.用于预览.

2.调用MediaCamera静态检測方法对设备检測.

3.对MediaCamera中前后置摄像头相关參数进行设定.

/* 拍照參数 */MediaCamera.setDefaultImagePath( );

MediaCamera.initCameraParameters_back( );

MediaCamera.initCameraParameters_front( );

/* 摄像參数 */

MediaCamera.setDefaultVedioPath( );

MediaCamera.initRecordParameters_back( );

MediaCamera.initRecordParameters_front( );

4. new MediaCamera()传入SurfaceView.

5. takePhoto()拍照

6. startRecording();

stopRecording();

可通过isRecording标记推断拍摄是否完毕


资源已上传CSDN 地址:点此下载


欢迎拍砖指点,转载请注明出处,谢谢

个人封装的一个Camera类的更多相关文章

  1. SpringMVC 中,当前台传入多个参数时,可将参数封装成一个bean类

    在实际业务场景中,当前台通过 url 向后台传送多个参数时,可以将参数封装成一个bean类,在bean类中对各个参数进行非空,默认值等的设置. 前台 url ,想后台传送两个参数,userName 和 ...

  2. EUI ViewStack实现选项卡组件 (封装了一个UI类)

    封装一个选项卡的UI,用来应付游戏中各种需要选项卡的界面. 例如背包,背包界面的选项卡可以切换装备.物品.符文.宝箱. 下图方法的实现参考:EUI ViewStack实现选项卡组件 假如在主页Home ...

  3. 将CRUD封装到一个工具类中

    package org.zln.hibernate.utils; import org.hibernate.Session; import org.hibernate.SessionFactory; ...

  4. Directx11学习笔记【二十一】 封装键盘鼠标响应类

    原文:Directx11学习笔记[二十一] 封装键盘鼠标响应类 摘要: 本文由zhangbaochong原创,转载请注明出处:http://www.cnblogs.com/zhangbaochong/ ...

  5. 使用libzplay库封装一个音频类

    装载请说明原地址,谢谢~~      前两天我已经封装好一个duilib中使用的webkit内核的浏览器控件和一个基于vlc的用于播放视频的视频控件,这两个控件可以分别用在放酷狗播放器的乐库功能和MV ...

  6. 1.使用C++封装一个链表类LinkList

     使用C++封装一个链表类LinkList.写出相应一个测试用例 链表需要提供 添加 修改删除 除重 合并 排序创建 销毁等接口. 不能调用库函数或者使用STL等类库 题目延伸********** ...

  7. 基于Dapper二次封装了一个易用的ORM工具类:SqlDapperUtil

    基于Dapper二次封装了一个易用的ORM工具类:SqlDapperUtil,把日常能用到的各种CRUD都进行了简化封装,让普通程序员只需关注业务即可,因为非常简单,故直接贴源代码,大家若需使用可以直 ...

  8. Timber(对Log类封装的一个工具)

    Timber(对Log类封装的一个工具) https://blog.csdn.net/hzl9966/article/details/51314137 https://www.jianshu.com/ ...

  9. java---解析XML文件,通过反射动态将XML内容封装到一个类中

    本博客讲的XML解析,使用的是dom4j. 首先建立一个maven项目,在dom.xml中引入相应的dom4j的版本.作者下载的是热度很高的1.6.1版本.maven的使用在这里不做详细讲解. 引入成 ...

随机推荐

  1. JavaScript实现私有属性

    原文:JavaScript实现私有属性 JavaScript被很多人认为并不是一种面向对象语言,原因有很多种,比如JavaScript没有类,不能提供传统的类式继承:再比如JavaScript不能实现 ...

  2. Linux查看物理CPU个数、核数、逻辑CPU个数 (转)

    # 总核数 = 物理CPU个数 X 每颗物理CPU的核数 # 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 # 查看物理CPU个数 cat /proc/cpuinfo| ...

  3. linux之SQL语句简明教程---SELECT

    SQL是用来做什么的呢?一个最常用的方式是将资料从数据库中的表格内选出.从这一句回答中,我们马上可以看到两个关键字: 从 (FROM) 数据库中的表格内 选出 (SELECT).(表格是一个数据库内的 ...

  4. 关于VMware导入Linux VM找不到网卡的问题

    今天遇到一个问题:由于虚拟机升级,导致以前的Linux VM(CentoS 6.7)在新的VMware里面打开,系统提示找不到网卡的问题,在网上找了好多解决办法,基本上都是一样的答案. 与网卡有关的几 ...

  5. 使用Mysql.data.dll文件在服务器上运行访问Mysql

    我使用的这个Mysql.data.dll文件 web.config上面主要需要声明以下代码 <system.data> <DbProviderFactories> <ad ...

  6. cocos2d-x 学习笔记一(概述)

    1.游戏-可控制的动画-连续的静态图像 2.关键帧驱动游戏 3.事件驱动型游戏 4.cocos2d-x 1.0 opengl-es 1.0;cocos2d-x 2.x opengl-es 2.0;co ...

  7. Java替代C语言的可能性

        前不久CSDN刊登了一篇<C语言已经死了>的文章,引起了一些争论.事实上那篇文章是从Ed Burnette的博客上转载来的,原文题目是“Die, C, die!”,直译过来应该是& ...

  8. mysql数据库的物理文件结构

    mysql两种常用存储引擎myisam和innodb myisam不支持事务:innodb支持事务,当前作为插件来安装 myisam的数据库的物理文件结构为: .frm文件:与表相关的元数据信息都存放 ...

  9. 在Activity中动态设置TextView的隐藏属性

    if (true) { //显示 viewHolder.tvLine.setVisibility(View.INVISIBLE);} else { //不显示 viewHolder.tvLine.se ...

  10. ES6笔记① var 和 let的区别

    let 和 var的区别    答:不同点在于作用域 1.(全局下)首先  let关键字声明的变量是这样写会导致错误. let声明的变量类似于”本地变量“,函数内如何不重新声明,还是会被改变 var ...