Android(安卓)开发之对拍照和录像功能的封装
16lz
2021-01-26
Android 开发之对拍照和录像功能的封装
转载请注明出处 传送门 本文出自【付小华的博客】
介绍:
关于Android 自定义相机和自定义录像功能的封装有很多,我这里也封装了一个,与其它的不同,我这里是非常简便和轻量级的封装,只有一个类(继承自TextureView),大家使用时只需要复制这个类就可以了。
使用:
- 权限声明
"android.permission.CAMERA" />"android.permission.RECORD_AUDIO" />"android.permission.READ_EXTERNAL_STORAGE" />"android.permission.WRITE_EXTERNAL_STORAGE" />
- 布局引用
<xxxxxxx.TextureCameraPreview android:id="@+id/texture_camera_view" android:layout_width="match_parent" android:layout_height="match_parent" />
- 拍照
只需要在布局中引用即可直接打开相机预览。
/** * 拍照 * * @param listener 拍照监听,不可空 */ public void takePicture(OnPictureTakenListener listener)
// 声明变量TextureCameraPreview mTextureCameraPreview;// 拍照mTextureCameraPreview.takePicture(new TextureCameraPreview.OnPictureTakenListener() { @Override public void onSuccess(byte[] data) { //TODO 拍照成功时回调 } @Override public void onFailed(String msg) { //TODO 拍照失败时回调 }});
- 录像
只需要在布局中引用即可直接打开相机预览。
/** * 开始录像 * * @param outputPath 输出录像保存文件路径,如"test.mp4" * @param listener 录像开始结束的监听,可空 */ public void startRecord(String outputPath, OnStartVideoListener listener)
// 声明变量TextureCameraPreview mTextureCameraPreview;// 录像// 判断是否正处于录像if (!mTextureCameraPreview.isRecording()) { mTextureCameraPreview.startRecord("test.mp4", new TextureCameraPreview.OnStartVideoListener() { @Override public void onStart() { // TODO: 开始录像时的回调 } @Override public void onStop() { // TODO: 录像结束时的回调 } });}// 需要在onPause中结束录像@Overridepublic void onPause() { super.onPause(); if (mTextureCameraPreview.isRecording()) { // 结束录像 mTextureCameraPreview.stopRecord(); }}
- 其它方法
/** * 预览界面放大 * * @param progress 放大倍数 0-100 */ public void setZoom(int progress)
/** * 切换前后置摄像头 * * @param index 0为后置摄像头,1为前置摄像头 */ public void switchCamera(int index)
代码:
import android.content.Context;import android.graphics.SurfaceTexture;import android.hardware.Camera;import android.media.AudioManager;import android.media.CamcorderProfile;import android.media.MediaRecorder;import android.media.ToneGenerator;import android.os.AsyncTask;import android.util.AttributeSet;import android.view.TextureView;import android.widget.Toast;/** * Created by shenhua on 3/29/2017. * Email shenhuanet@126.com */public class TextureCameraPreview extends TextureView implements TextureView.SurfaceTextureListener, Camera.PictureCallback, Camera.ShutterCallback { private Camera mCamera; private int index = 0; private OnPictureTakenListener onPictureTakenListener; private MediaRecorder mMediaRecorder; private boolean isRecording = false; private OnStartVideoListener onStartVideoListener; private SurfaceTexture mSurface; public TextureCameraPreview(Context context) { this(context, null); } public TextureCameraPreview(Context context, AttributeSet attrs) { this(context, attrs, 0); } public TextureCameraPreview(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setSurfaceTextureListener(this); } @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { mSurface = surface; openCamera(); } private void openCamera() { // 1.打开相机 mCamera = getCameraInstance(getContext(), index); if (mCamera != null) { // 2.设置相机参数 Camera.Parameters parameters = mCamera.getParameters(); // 3.调整预览方向 mCamera.setDisplayOrientation(90); // 4.设置预览尺寸 parameters.setPreviewSize(1920, 1080); parameters.setPictureSize(1920, 1080); // 5.调整拍照图片方向 if (index == 0) parameters.setRotation(90); if (index == 1) parameters.setRotation(270); mCamera.setParameters(parameters); // 6.开始相机预览 try { mCamera.setPreviewTexture(mSurface); mCamera.startPreview(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(getContext(), "Error setting camera preview:" + e.getMessage(), Toast.LENGTH_SHORT).show(); } } } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { releaseCamera(); return true; } private void releaseCamera() { if (mCamera != null) { mCamera.stopPreview(); mCamera.release(); mCamera = null; } } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { } public static Camera getCameraInstance(Context context, int i) { Camera c = null; try { c = Camera.open(i); } catch (Exception e) { Toast.makeText(context, "相机打开失败", Toast.LENGTH_SHORT).show(); } return c; } public void takePicture(OnPictureTakenListener listener) { if (listener != null) { onPictureTakenListener = listener; if (mCamera != null) { mCamera.takePicture(this, null, this); } else { onPictureTakenListener.onFailed("拍照失败"); } } } public void setZoom(int progress) { if (mCamera != null) { Camera.Parameters parameters = mCamera.getParameters(); parameters.setZoom((int) (progress * 1.0f / (40 * 100) * 40)); mCamera.setParameters(parameters); } } public void switchCamera(int index) { if (isRecording) { stopRecord(); } releaseCamera(); this.index = index; openCamera(); } @Override public void onPictureTaken(byte[] data, Camera camera) { Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); if (index == 1) { bitmap = reversalBitmap(bitmap, -1, 1); } if (onPictureTakenListener != null) { onPictureTakenListener.onSuccess(bitmap); } // 使拍照结束后重新预览 releaseCamera(); openCamera(); } private Bitmap reversalBitmap(Bitmap srcBitmap, float sx, float sy) { Bitmap cacheBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Bitmap.Config.ARGB_8888); int w = cacheBitmap.getWidth(); int h = cacheBitmap.getHeight(); Canvas canvas = new Canvas(cacheBitmap); Matrix matrix = new Matrix(); matrix.postScale(sx, sy); Bitmap bitmap = Bitmap.createBitmap(srcBitmap, 0, 0, w, h, matrix, true); canvas.drawBitmap(bitmap, new Rect(0, 0, srcBitmap.getWidth(), srcBitmap.getHeight()), new Rect(0, 0, w, h), null); return bitmap; } @Override public void onShutter() { } public interface OnPictureTakenListener { void onSuccess(Bitmap bitmap); void onFailed(String msg); }// ---------------- 录像 private boolean initMediaRecorder(String outputPath) { mMediaRecorder = new MediaRecorder(); if (mCamera != null) { // 1.解锁并将相机设置daoMediaRecorder mCamera.unlock(); mMediaRecorder.setCamera(mCamera); // 2.设置资源 mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 3.设置CamcorderProfile(需要API级别8或更高版本) mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); // 4.设置输出文件 mMediaRecorder.setOutputFile(outputPath); // 5.准备配置的MediaRecorder try { mMediaRecorder.prepare(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(getContext(), "录像配置准备失败", Toast.LENGTH_SHORT).show(); releaseMediaRecorder(); return false; } return true; } return false; } private void releaseMediaRecorder() { if (mMediaRecorder != null) { mMediaRecorder.reset(); mMediaRecorder.release(); mMediaRecorder = null; } } public void startRecord(String outputPath, OnStartVideoListener listener) { this.onStartVideoListener = listener; if (initMediaRecorder(outputPath)) { new MediaPrepareTask(listener).execute(); } else { Toast.makeText(getContext(), "开始录制视频失败", Toast.LENGTH_SHORT).show(); } } public void stopRecord() { if (isRecording) { mMediaRecorder.stop(); releaseMediaRecorder(); mCamera.lock(); if (onStartVideoListener != null) onStartVideoListener.onStop(); } else { releaseMediaRecorder(); } isRecording = false; } public boolean isRecording() { return isRecording; } class MediaPrepareTask extends AsyncTask { OnStartVideoListener listener; MediaPrepareTask(OnStartVideoListener listener) { this.listener = listener; } @Override protected Boolean doInBackground(Void... params) { mMediaRecorder.start(); isRecording = true; return true; } @Override protected void onPostExecute(Boolean aBoolean) { super.onPostExecute(aBoolean); if (listener != null) listener.onStart(); } } public interface OnStartVideoListener { void onStart(); void onStop(); }}
至此,正文结束,如大家遇到问题,欢迎评论、私信或邮件。
更多相关文章
- Android(安卓)2.2 带来全新拍照增强特性
- Android(安卓)Developers:简单的拍照
- 2013新春奉送:Android摄像头开发完美demo---(循环聚焦,缩放大小,
- 基于android的远程视频监控系统——实现,
- Android基础知识复习之打开照相机拍照并获取照片
- 在Android中使用OpenGL ES开发第(四)节:相机预览
- Skype for Business预览版已登陆Android和iOS平台
- Android(安卓)Camera应用初探三
- 【Android(安卓)Training - Multimedia】捕获照片 [Lesson 3 -