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

新工作是搞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. 深入浅出畅谈Zigbee

    ZigBee采用802.15.4标准作为其对等通信的基础.该标准由ZigBee联盟(ZigBee Alliance)开发并管理.ZigBee Alliance是一家投资于该标准并在无线领域进行推广的联 ...

  2. C# 线程池异步调用

    许多应用程序使用多个线程,但这些线程经常在休眠状态中耗费大量的时间来等待事件发生.其他线程可能进入休眠状态,并且仅定期被唤醒以轮询更改或更新状态信息,然后再次进入休眠状态.为了简化对这些线程的管理,. ...

  3. C#多显示器转换的两种方法——SetWindowPos,Screen

    原文 http://blog.csdn.net/hejialin666/article/details/6057551 实现多屏显示目的:一般情况下是一个电脑显示屏,外接一个电视显示屏.在电脑上显示的 ...

  4. JavaEE Tutorials (25) - 使用Java EE拦截器

    25.1拦截器概述380 25.1.1拦截器类381 25.1.2拦截器生命周期381 25.1.3拦截器和CDI38125.2使用拦截器381 25.2.1拦截方法调用382 25.2.2拦截生命周 ...

  5. JOSM学习下载地址

    JOSM is an extensible editor for ​OpenStreetMap (OSM) written in ​Java 7. Currently it supports load ...

  6. linux之SQL语句简明教程---UNION ALL

    UNION ALL 这个指令的目的也是要将两个 SQL 语句的结果合并在一起. UNION ALL 和UNION 不同之处在于 UNION ALL 会将每一笔符合条件的资料都列出来,无论资料值有无重复 ...

  7. IKAnalyzer使用停用词词典进行分词

    @Test // 測试分词的效果,以及停用词典是否起作用 public void test() throws IOException { String text = "老爹我们都爱您.&qu ...

  8. WAV文件格式分析

    一. RIFF概念 在Windows环境下,大部分的多媒体文件都依循着一种结构来存放信息,这样的结构称为"资源互换文件格式"(Resources lnterchange File ...

  9. 修改Chrome的User Agent的方法 真实有效

    如何修改Chrome的User Agent: 通过网络上查找,修改Chrome的Usre Agent有3种方式,但有的方式是不起作用的. 给Chrome添加启动参数(有作用) 通过扩展-User-Ag ...

  10. oracle em命令行配置及界面按钮乱码问题解决方法

    一.配置EM dbconsole db [oracle@rusky ~]$ lsnrctl start [oracle@rusky ~]$ emctl start dbconsoleTZ set to ...