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" />
  1. 拍照
    只需要在布局中引用即可直接打开相机预览。
    /**     * 拍照     *     * @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 拍照失败时回调    }});
  1. 录像
    只需要在布局中引用即可直接打开相机预览。
    /**     * 开始录像     *     * @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();    }}

至此,正文结束,如大家遇到问题,欢迎评论、私信或邮件。

更多相关文章

  1. Android(安卓)2.2 带来全新拍照增强特性
  2. Android(安卓)Developers:简单的拍照
  3. 2013新春奉送:Android摄像头开发完美demo---(循环聚焦,缩放大小,
  4. 基于android的远程视频监控系统——实现,
  5. Android基础知识复习之打开照相机拍照并获取照片
  6. 在Android中使用OpenGL ES开发第(四)节:相机预览
  7. Skype for Business预览版已登陆Android和iOS平台
  8. Android(安卓)Camera应用初探三
  9. 【Android(安卓)Training - Multimedia】捕获照片 [Lesson 3 -

随机推荐

  1. 更新Android SDK Manager Mac下修改hosts
  2. Android反编译工具:Apktool,支持Linux 、Wi
  3. Android游戏开发系列教程第三讲(事件处理)
  4. android逐行读取文件内容以及保存为文件
  5. 如何查看android的wifi密码?究竟保存在哪
  6. Android(安卓)按压效果的工具类
  7. Android中Handler的使用2
  8. 在android 输出log 信息 用于调试
  9. Android开发环境搭建(WINDOWS VERSION)
  10. Android Day03-SQLite数据库操作及ListVi