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

新工作是搞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 地址:点此下载


欢迎拍砖指点,转载请注明出处,谢谢
04-14 19:44