Android Camera的使用 (一)
来源:互联网 发布:京东面试题java 编辑:程序博客网 时间:2024/06/11 19:20
一、前言
在android 5.0 之后 官方已经不推荐Camear这个类了,而是推荐 android.hardware.camera2 包下的api.但我们还是有必要学习一下。
Camera这个类可以被用来照相、start/top相机预览、将图像帧编码成video。它对于相机服务相当于一个客户端,它管理者真正的硬件Camera。
要访问硬件Camera我们必须在AndroidManifest.xml中声明相机权限。还必须确保AndroidManifest.xml 包含相机功能的声明( < uses- feature >)。比如如果想使用相机的 auto-focus,就必须在AndroidManifest.xml中声明:
<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
使用这个类照相可以分为以下几步:
1、使用 Camera的 opent(int).创建一个实例
2、通过getParameters(). 获得默认的参数
3、如果必要的话,通过setParameters(Camera.Parameters). 修改参数
4、使用 setDisplayOrientation(int)改正当前预览的方向
5、初始化一个SurfaceHolder,并通过 setPreviewDisplay(SurfaceHolder). 设置,如果没有设置将不能开始预览
6、 调用startPreview()开始预览,拍照前必须开始预览
7、调用 takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback) 等待image 数据
8、拍完照之后,如果还想继续拍照重新调用 startPreview()
9、调用 stopPreview()停止预览
10、调用 release() 释放。应用程序应该在 onPause()时立即调用该方法,在onResume重新打开。
使用这个类录像分为以下几步:
1、和上文描述的一样 创建一个实例,之后开启预览
2、调用unlock() 去允许media process 访问camera
3、通过MediaRecord的 setCamera(Camear camera)
4、当结束录制之后,调用reconnect() 去请求,并re-lock Camera
5、如果希望继续拍照或者录像,重新调用 startPreviews()
6、调用stopPreview() 和 release()结束
下面是一个简单的拍照示例:
public class CameraActivity extends BaseActivity { private static final String TAG = "CameraActivity"; @BindView(R.id.btn_take_picture) Button btnTakePicture; @BindView(R.id.btn_start_record) Button btnStartRecord; @BindView(R.id.surfaceView) SurfaceView surfaceView; private SurfaceHolder holder; private Camera mCamera; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.act_camera); ButterKnife.bind(this); initView(); } private void initCamera() { /** * Step 1. * 获得一个Camera实例,(默认获得为后置摄像头) */ if(mCamera==null){ mCamera = Camera.open(); } /** * Step 2. * 获得默认的参数 */ Camera.Parameters parameters = mCamera.getParameters(); parameters.setPictureFormat(ImageFormat.JPEG); /** * Stop 3. * 设置参数 */ mCamera.setParameters(parameters); /** * Step 4. * 修正当前的方向 */ setCameraDisplayOrientation(this, Camera.CameraInfo.CAMERA_FACING_BACK, mCamera); /** * Step 5. * 设置 SurfaceHolder */ try { mCamera.setPreviewDisplay(holder); } catch (IOException e) { e.printStackTrace(); } /** * Step 6. * 开始预览 */ mCamera.startPreview(); } public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay() .getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); } private void initView() { holder = surfaceView.getHolder(); holder.addCallback(callback); holder.setKeepScreenOn(true); } @Override protected void onResume() { super.onResume(); Log.i(TAG, "onResume: "); initCamera(); } @Override protected void onPause() { super.onPause(); Log.i(TAG, "onPause: "); /** * Step 9. 停止预览 */ mCamera.stopPreview(); /** * Step 10. 释放 */ mCamera.release(); mCamera = null; } @OnClick({R.id.btn_take_picture, R.id.btn_start_record}) public void onClick(View view) { switch (view.getId()) { case R.id.btn_take_picture: /** * Step 7. * 拍照 */ mCamera.takePicture(null, null, null, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { if (data != null) { /** * Step 8. 重新开始预览 */ mCamera.startPreview(); writeImage2Sdcard(data); } } }); break; case R.id.btn_start_record: break; } } private void writeImage2Sdcard(final byte[] data) { new Thread() { @Override public void run() { FileOutputStream out = null; try { out = new FileOutputStream(new File("sdcard/test", System.currentTimeMillis() + ".jpg")); out.write(data); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } }.start(); } private SurfaceHolder.Callback callback = new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { initCamera(); Log.i(TAG, "surfaceCreated: "); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.i(TAG, "surfaceChanged: "); setCameraDisplayOrientation(CameraActivity.this, Camera.CameraInfo.CAMERA_FACING_BACK,mCamera); } @Override public void surfaceDestroyed(SurfaceHolder holder) { Log.i(TAG, "surfaceDestroyed: "); } };
如果需要录制视频的话加入以下代码:
if (!started) { started = true; btnStartRecord.setText("结束录像"); mediaRecorder = new MediaRecorder(); /** * 录像 Step A. */ mCamera.unlock(); /** * 录像 Step B. */ mediaRecorder.setCamera(mCamera); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); mediaRecorder.setOutputFile(Environment.getExternalStorageDirectory()+ File.separator+System.currentTimeMillis()+".3gp"); try { mediaRecorder.prepare(); } catch (IOException e) { e.printStackTrace(); } mediaRecorder.start();// } else { started = false; btnStartRecord.setText("开始录像"); mediaRecorder.stop(); mediaRecorder.reset(); mediaRecorder.release(); /** * 录像 Step C. */ try { mCamera.reconnect(); } catch (IOException e) { e.printStackTrace(); } mCamera.lock(); /** * 录像 Step D. */ mCamera.startPreview(); }
最后完整代码如下:
public class CameraActivity extends BaseActivity { private static final String TAG = "CameraActivity"; @BindView(R.id.btn_take_picture) Button btnTakePicture; @BindView(R.id.btn_start_record) Button btnStartRecord; @BindView(R.id.surfaceView) SurfaceView surfaceView; private SurfaceHolder holder; private Camera mCamera; private MediaRecorder mediaRecorder; private boolean started; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.act_camera); ButterKnife.bind(this); initView(); } private void initCamera() { /** * Step 1. * 获得一个Camera实例,(默认获得为后置摄像头) */ if (mCamera == null) { mCamera = Camera.open(); } /** * Step 2. * 获得默认的参数 */ Camera.Parameters parameters = mCamera.getParameters(); parameters.setPictureFormat(ImageFormat.JPEG); /** * Stop 3. * 设置参数 */ mCamera.setParameters(parameters); /** * Step 4. * 修正当前的方向 */ setCameraDisplayOrientation(this, Camera.CameraInfo.CAMERA_FACING_BACK, mCamera); /** * Step 5. * 设置 SurfaceHolder */ try { mCamera.setPreviewDisplay(holder); } catch (IOException e) { e.printStackTrace(); } /** * Step 6. * 开始预览 */ mCamera.startPreview(); } public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay() .getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); } private void initView() { holder = surfaceView.getHolder(); holder.addCallback(callback); holder.setKeepScreenOn(true); } @Override protected void onResume() { super.onResume(); Log.i(TAG, "onResume: "); initCamera(); } @Override protected void onPause() { super.onPause(); Log.i(TAG, "onPause: "); /** * Step 9. 停止预览 */ mCamera.stopPreview(); /** * Step 10. 释放 */ mCamera.release(); mCamera = null; } @OnClick({R.id.btn_take_picture, R.id.btn_start_record}) public void onClick(View view) { switch (view.getId()) { case R.id.btn_take_picture: /** * Step 7. * 拍照 */ mCamera.takePicture(null, null, null, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { if (data != null) { /** * Step 8. 重新开始预览 */ mCamera.startPreview(); writeImage2Sdcard(data); } } }); break; case R.id.btn_start_record: if (!started) { started = true; btnStartRecord.setText("结束录像"); mediaRecorder = new MediaRecorder(); /** * 录像 Step A. */ mCamera.unlock(); /** * 录像 Step B. */ mediaRecorder.setCamera(mCamera); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); mediaRecorder.setOutputFile(Environment.getExternalStorageDirectory()+ File.separator+System.currentTimeMillis()+".3gp"); try { mediaRecorder.prepare(); } catch (IOException e) { e.printStackTrace(); } mediaRecorder.start();// } else { started = false; btnStartRecord.setText("开始录像"); mediaRecorder.stop(); mediaRecorder.reset(); mediaRecorder.release(); /** * 录像 Step C. */ try { mCamera.reconnect(); } catch (IOException e) { e.printStackTrace(); } mCamera.lock(); /** * 录像 Step D. */ mCamera.startPreview(); } break; } } private void writeImage2Sdcard(final byte[] data) { new Thread() { @Override public void run() { FileOutputStream out = null; try { out = new FileOutputStream(new File("sdcard/test", System.currentTimeMillis() + ".jpg")); out.write(data); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } }.start(); } private SurfaceHolder.Callback callback = new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { initCamera(); Log.i(TAG, "surfaceCreated: "); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.i(TAG, "surfaceChanged: "); setCameraDisplayOrientation(CameraActivity.this, Camera.CameraInfo.CAMERA_FACING_BACK, mCamera); } @Override public void surfaceDestroyed(SurfaceHolder holder) { Log.i(TAG, "surfaceDestroyed: "); } };}
权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission> <uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.CAMERA"></uses-permission> <uses-feature android:name="android.hardware.camera"></uses-feature> <uses-feature android:name="android.hardware.camera.autofocus"></uses-feature> <uses-permission android:name="android.permission.RECORD_AUDIO" />
- Android Camera的使用 (一)
- Android Camera的使用(一)
- Android Camera(一)
- Android Camera(一)
- Android Camera的使用
- Android Camera的使用 (二)
- Dragonboard410c Android USB Camera 使用:mjpg-streamer介绍(一)
- Android Camera 明细(一)
- <英译中>Android Camera(一)
- Android Camera 明细(一)
- Android Camera的使用 (三)
- AR Camera开发记录(一) -- Rajawali的使用
- Android Camera (一)通过Intent 拍照
- Android Camera 实时滤镜(一)
- android Camera照相机技术(一)
- Android Camera开发(一)之基础知识
- Android Camera 正方形预览(一)
- Android Camera开发(一)之基础知识
- 分蛋糕
- GUI与UI的区别
- hdoj 1576 A/B [扩展欧几里得.逆元]
- 遍历文件夹中的文件(以图片为例)
- Web应用设置统一错误友好界面
- Android Camera的使用 (一)
- POJ3349——Snowflake Snow Snowflakes
- 使用C++类的成员函数来做windows的窗口函数
- refresh的停车场
- 东芝硬盘数据丢失怎么恢复
- mysql索引的实现原理
- 课程【 判断链表是否有环】
- Android屏幕密度(Density)和分辨率的关系
- 【置顶】经典背包讲解01背包&&完全背包&&多重背包