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

新工作是搞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. Arduino红外遥控系列教程2013——发射与接收

    教程一:红外接收教程本教程共四步操作,将教大家如何收集电视红外遥控器的编码 视频链接:http://v.youku.com/v_show/id_XNTE2NjQ5NTcy.html 第一步:电路连接, ...

  2. android邮件发送几种方式

    android中发送邮件我大概发现了3种,代码如下 package src.icetest; import org.apache.commons.mail.EmailException; import ...

  3. HttpClient post 请求实例

    所需jar包: commons-codec-1.3.jar commons-httpclient-3.0.jar commons-logging-1.1.1.jar /** * */ package ...

  4. Jmeter性能测试 及压测入门

    Jmeter是一个非常好用的压力测试工具.  Jmeter用来做轻量级的压力测试,非常合适,只需要十几分钟,就能把压力测试需要的脚本写好. 为什么要建立线程组?原因很简单,因为我们要模拟多个线程(用户 ...

  5. 【hihocoder 1258 Osu! Master】

    2015北京区域赛现场赛签到题. 题面:http://media.hihocoder.com/contests/icpcbeijing2015/problems.pdf OJ链接:http://hih ...

  6. linux底半部机制在视频采集驱动中的应用

    最近在做一个arm+linux平台的视频驱动.本来这个驱动应该是做板子的第三方提供的,结果对方软件实力很差,自己做不了这个东西,外包给了一个暑期兼职的在读博士.学生嘛,只做过实验,没做过产品,给出的东 ...

  7. [网络分析]WEBQQ3.0协议分析---good good study

    声明:研究学习使用,严禁商业化~~噗嗤,估计也没有商业化的 本文地址:http://blog.csdn.net/sushengmiyan/article/details/11906101 作者:sus ...

  8. x/nfu-用gdb查看内存

    用gdb查看内存 2007-12-08 12:43 用gdb查看内存 格式: x /nfu <addr> 说明x 是 examine 的缩写 n表示要显示的内存单元的个数 f表示显示方式, ...

  9. C# in Depth阅读笔记1:C#1特性

    1.委托 委托是对包含返回值和参数的行为的一种封装,类似于单一方法的接口. 委托是不易变的(就像string),system.delegate下的combine和remove方法都只能产生一个新的委托 ...

  10. RequiredFieldValidator验证下拉列表框

    <asp:DropDownList ID="DropDownList1" runat="server" CssClass="style01&qu ...