个人封装的一个Camera类
好久不写博客了,代码写了不少,但大多数都是拿来主义,要不是网上,要不就是自己曾经的代码拼装。
新工作是搞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类的更多相关文章
- SpringMVC 中,当前台传入多个参数时,可将参数封装成一个bean类
在实际业务场景中,当前台通过 url 向后台传送多个参数时,可以将参数封装成一个bean类,在bean类中对各个参数进行非空,默认值等的设置. 前台 url ,想后台传送两个参数,userName 和 ...
- EUI ViewStack实现选项卡组件 (封装了一个UI类)
封装一个选项卡的UI,用来应付游戏中各种需要选项卡的界面. 例如背包,背包界面的选项卡可以切换装备.物品.符文.宝箱. 下图方法的实现参考:EUI ViewStack实现选项卡组件 假如在主页Home ...
- 将CRUD封装到一个工具类中
package org.zln.hibernate.utils; import org.hibernate.Session; import org.hibernate.SessionFactory; ...
- Directx11学习笔记【二十一】 封装键盘鼠标响应类
原文:Directx11学习笔记[二十一] 封装键盘鼠标响应类 摘要: 本文由zhangbaochong原创,转载请注明出处:http://www.cnblogs.com/zhangbaochong/ ...
- 使用libzplay库封装一个音频类
装载请说明原地址,谢谢~~ 前两天我已经封装好一个duilib中使用的webkit内核的浏览器控件和一个基于vlc的用于播放视频的视频控件,这两个控件可以分别用在放酷狗播放器的乐库功能和MV ...
- 1.使用C++封装一个链表类LinkList
使用C++封装一个链表类LinkList.写出相应一个测试用例 链表需要提供 添加 修改删除 除重 合并 排序创建 销毁等接口. 不能调用库函数或者使用STL等类库 题目延伸********** ...
- 基于Dapper二次封装了一个易用的ORM工具类:SqlDapperUtil
基于Dapper二次封装了一个易用的ORM工具类:SqlDapperUtil,把日常能用到的各种CRUD都进行了简化封装,让普通程序员只需关注业务即可,因为非常简单,故直接贴源代码,大家若需使用可以直 ...
- Timber(对Log类封装的一个工具)
Timber(对Log类封装的一个工具) https://blog.csdn.net/hzl9966/article/details/51314137 https://www.jianshu.com/ ...
- java---解析XML文件,通过反射动态将XML内容封装到一个类中
本博客讲的XML解析,使用的是dom4j. 首先建立一个maven项目,在dom.xml中引入相应的dom4j的版本.作者下载的是热度很高的1.6.1版本.maven的使用在这里不做详细讲解. 引入成 ...
随机推荐
- "NO 3D support is available from the host"
https://forums.opensuse.org/showthread.php/494522-No-3d-Support-or-graphics-accelleration http://ask ...
- linux命令之uname
uname是linux中查询系统基本信息的命令. 命令形式: uname [选项] 选项包括:(若不跟任何选项:则默认-s选项) -s, --kernel-name 输出内核名称 -n, --no ...
- Linux 零碎知识点
ln -s ../libs/ libs 在当前目录下建立一个符号链接文件libs,使它指向上一层目录的libs文件夹 关于su和su -的区别切换用户是可以使用su tom或者su - tom来实现, ...
- hdu 5616 Jam's balance(dp 正反01背包)
来自官方题解: AC代码: #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream ...
- 依赖注入及AOP简述(八)——混合请求模式 .
2.3. 混合请求模式 上一节讲到了FQCN(全类名)请求模式会带来依赖定义的柔软性较差的问题,因此字符串和全类名混合的模式又应运而生了.比如刚才的Spring中的API方式声明注入点的例子就可 ...
- GetBuffer与ReleaseBuffer的用法,CString剖析
转载: http://blog.pfan.cn/xman/43212.html GetBuffer()主要作用是将字符串的缓冲区长度锁定,releaseBuffer则是解除锁定,使得CString对象 ...
- Spring-----代码中使用注入的Properties配置属性
转载自:http://blog.csdn.net/hekewangzi/article/details/49990799
- mysql和VS2010 C++链接过程中出现的问题
PS:二者连接的过程主要参考这篇博客园文章,http://www.cnblogs.com/justinzhang/archive/2011/09/23/2185963.html 这篇博客园的文章中的代 ...
- BZOJ 4008: [HNOI2015]亚瑟王( dp )
dp(i, j)表示考虑了前i张牌, 然后还有j轮的概率. 考虑第i+1张牌: 发动的概率 : p = dp(i, j) * (1 - (1-p[i+1])^j) 没发动的概率 : dp(i, j) ...
- Java log4j的环境搭建
一.Log4j是什么? Log4j是Apache的一个开源代码项目,通过使用Log4j,我们可以控制日志信息输出的目的地.最常见的就是输出到控制台或者日志文件.同时,它强大的一点是可以在C.C++等其 ...