Android API之CameraPreview
来源:互联网 发布:怎么查询域名是否备案 编辑:程序博客网 时间:2024/05/17 22:22
@SuppressWarnings("deprecation")public class CameraPreview extends Activity { private Preview mPreview; Camera mCamera; int numberOfCameras; int cameraCurrentlyLocked; int defaultCameraId; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //设置全屏显示 requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); //初始化界面 mPreview = new Preview(this); setContentView(mPreview); //找到可用的相机数量 numberOfCameras = Camera.getNumberOfCameras(); // 查找默认相机的标识 CameraInfo cameraInfo = new CameraInfo(); for (int i = 0; i < numberOfCameras; i++) { Camera.getCameraInfo(i, cameraInfo); if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) { defaultCameraId = i; } } } @Override protected void onResume() { super.onResume(); // 打开默认的即第一个后置摄像头。 mCamera = Camera.open(); cameraCurrentlyLocked = defaultCameraId; mPreview.setCamera(mCamera); } @Override protected void onPause() { super.onPause(); //不使用地时候需要释放 资源 if (mCamera != null) { mPreview.setCamera(null); mCamera.release(); mCamera = null; } } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.camera_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.switch_cam: if (numberOfCameras == 1) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(this.getString(R.string.camera_alert)) .setNeutralButton("Close", null); AlertDialog alert = builder.create(); alert.show(); return true; } if (mCamera != null) { mCamera.stopPreview(); mPreview.setCamera(null); mCamera.release(); mCamera = null; } mCamera = Camera .open((cameraCurrentlyLocked + 1) % numberOfCameras); cameraCurrentlyLocked = (cameraCurrentlyLocked + 1) % numberOfCameras; mPreview.switchCamera(mCamera); mCamera.startPreview(); return true; default: return super.onOptionsItemSelected(item); } }}/** * 自定义 ViewGroup:简单的包装在一个摄像头和一个图形渲染一个中心预览相机表面。 * 我们利用SurfaceView来处理预览,因为并不是所有的设备有摄像头,支持预览大小相同的纵横比为设备的显示。 */@SuppressWarnings("deprecation")class Preview extends ViewGroup implements SurfaceHolder.Callback { private final String TAG = "Preview"; // 预览画面的SurfaceView SurfaceView mSurfaceView; // SurfaceHolder接:控制surface的大小和格式, 在surface上编辑像素及监视surace的改变等 。 SurfaceHolder mHolder; // 预览画面的大小 Size mPreviewSize; List<Size> mSupportedPreviewSizes; // 相机 Camera mCamera; Preview(Context context) { super(context); mSurfaceView = new SurfaceView(context); //添加View addView(mSurfaceView); //初始化SurfaceHolder mHolder = mSurfaceView.getHolder(); //绑定监听接口 mHolder.addCallback(this); //设置类型 //SURFACE_TYPE_PUSH_BUFFERS表明该Surface不包含原生数据,Surface用到的数据由其他对象提供, //在Camera图像预览中就使用该类型的Surface,有Camera负责提供给预览Surface数据,这样图像预览会比较流畅 //http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1201/656.html mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } // 相机设置 public void setCamera(Camera camera) { mCamera = camera; if (mCamera != null) { // 获取摄像头所支持的所有分辨率 mSupportedPreviewSizes = mCamera.getParameters() .getSupportedPreviewSizes(); requestLayout(); } } public void switchCamera(Camera camera) { setCamera(camera); try { //设置预览展示 camera.setPreviewDisplay(mHolder); } catch (IOException exception) { Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); } //获取相机配置 参数 Camera.Parameters parameters = camera.getParameters(); //设置预览大小 parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); requestLayout(); //给相机设置参数 camera.setParameters(parameters); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //摄像头不是所有随便的(w, h)都能够认识的,所以在onMeasure()方法中进行处理 final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); setMeasuredDimension(width, height); if (mSupportedPreviewSizes != null) { mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if (changed && getChildCount() > 0) { final View child = getChildAt(0); final int width = r - l; final int height = b - t; int previewWidth = width; int previewHeight = height; if (mPreviewSize != null) { previewWidth = mPreviewSize.width; previewHeight = mPreviewSize.height; } if (width * previewHeight > height * previewWidth) { final int scaledChildWidth = previewWidth * height / previewHeight; child.layout((width - scaledChildWidth) / 2, 0, (width + scaledChildWidth) / 2, height); } else { final int scaledChildHeight = previewHeight * width / previewWidth; child.layout(0, (height - scaledChildHeight) / 2, width, (height + scaledChildHeight) / 2); } } } public void surfaceCreated(SurfaceHolder holder) { try { if (mCamera != null) { mCamera.setPreviewDisplay(holder); } } catch (IOException exception) { Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); } } public void surfaceDestroyed(SurfaceHolder holder) { if (mCamera != null) { mCamera.stopPreview(); } } //获取最佳的拍照或录像预览窗口大小 private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.1; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; // 试着找到一个尺寸匹配的纵横比和尺寸 for (Size size : sizes) { double ratio = (double) size.width / size.height; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } // 找不到一个匹配的纵横比,进行处理 if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { //预览大小是已知的,设置相机参数,并开始预览。 Camera.Parameters parameters = mCamera.getParameters(); parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); requestLayout(); mCamera.setParameters(parameters); mCamera.startPreview(); }}
0 0
- Android API之CameraPreview
- Android ApiDemos示例解析(57):Graphics->CameraPreview
- Android API之getSystemService
- android API之ActivityGroup
- android API之ActivityGroup
- android API之ActivityGroup
- Android API之CharSequence
- Android API 之Activity
- Android API 之 AsyncTask
- Android API之Handler
- Android API 之 Message
- Android API之ListFragment
- Android API之ProgressBar
- Android API之KeyStore
- Android之API详解
- ApiDemo 学习 CameraPreview 和 Clipping
- CameraPreView遇到的一些问题
- Android中文API之GridView
- servlet转发·重定向·包含常见问题
- ubuntu 16.04.1 u盘安装问题
- CI 实现无限级分类 \ 数据处理组合
- Android广播之发送广播的源码分析
- 如何在Eclipse上使用Espresso测试框架测试Android App
- Android API之CameraPreview
- HDU3746 Cyclic Nacklace KMP基础
- 单链表代码模板
- 使用ajax和window.history.pushState无刷新改变页面内容和地址栏URL
- CentOS上NTP服务的DDOS攻击解决办法
- dex分包 轻松解决解决65535的限制
- @RequestBody应用
- 那年的雨季
- 测试框架Mocha的使用