实现思路:点击拍照按钮后,获取摄像头的一帧数据,转换成jpg格式,保存到文件中。
Activity 继承Camera.PreviewCallback
重写public void onPreviewFrame(byte[] data, Camera camera);
首先创建MediaRecorder,Camera实例
创建camera
if (mCamera == null) {
mCamera = Camera.open();
}
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
mCamera.setPreviewCallback(this);
`
创建MediaRecorder:
if (mediaRecorder == null) {
mediaRecorder = new MediaRecorder();
}
设置mediaRecorder属性
mediaRecorder.reset();
***mediaRecorder.setCamera(mCamera);***
setVideoOrientation();
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); //从照相机采集视频
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setVideoSize(size.width, size.height);//设置分辨率
mediaRecorder.setVideoFrameRate(10);
mediaRecorder.setVideoEncodingBitRate(3 * 1024 * 1024);
setVideoMaxDuration();
File videoFile = new File(Tools.getPath(), fileName + ".3gp"); //保存路径及名称
mediaRecorder.setOutputFile(videoFile.getAbsolutePath());
try {
mediaRecorder.prepare();//预期准备
mediaRecorder.start();//开始刻录
} catch (Exception e) {
e.printStackTrace();
}
mHandler.sendEmptyMessageDelayed(MSG_START_RECORDER, 3000);//延时设置previewCallBack,防止回调消失。
在 onPreviewFrame(byte[] data, Camera camera)中获取一帧数据然后转换成jpg图片
数据处理放在线程中。isTakePic为拍照的标志位,当点击拍照按钮是置为true,开始从预览图像中获取一帧数据
public void onPreviewFrame(byte[] data, Camera camera) {
// At preview mode, the frame data will push to here.
FrameLaneData = data;//.clone();
FrameCarData = data;//.clone();
if (isTakePic) {
isTakePic = false;
shutterCallback.onShutter();
previewSize = mCamera.getParameters().getPreviewSize();
new Thread(new Runnable() {
@Override
public void run() {
try {
yunImage = new YuvImage(FrameLaneData, ImageFormat.NV21, previewSize.width, previewSize.height, null);
if (yunImage != null) {
ByteArrayOutputStream strem = new ByteArrayOutputStream();
yunImage.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 80, strem);
Bitmap bitmap = BitmapFactory.decodeByteArray(strem.toByteArray(), 0, strem.size());
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd_HHmmss");
String fileName = format.format(new Date());
File file = new File(Tools.getPath() + fileName + ".jpg");
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);//将图片压缩到流中
bos.flush();//输出
bos.close();//关闭
strem.close();
bitmap.recycle();
mHandler.sendEmptyMessage(MSG_TAKE_PICTURE);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
在开启录像之后可能会不执行回调方法,解决办法:在开启录像3s后再次设置回调,见代码注释。