自定义相机,使用前置摄像头实现自拍
来源:互联网 发布:win10输入法切换软件 编辑:程序博客网 时间:2024/04/19 13:28
通过Camera.open()获取相机,实现自定义自拍功能。
demo比较简单,直接上代码:
Activity
public class MainActivity extends AppCompatActivity { SurfaceView sView; SurfaceHolder surfaceHodler; int screenWidth, screenHeight; // 定义系统所用的照相机 Camera camera; // 是否存在预览中 boolean isPreview = false; private String filepath = "";//照片保存路径 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 获取窗口管理器 WindowManager wm = getWindowManager(); Display display = wm.getDefaultDisplay(); DisplayMetrics metrics = new DisplayMetrics(); // 获取屏幕的宽和高 display.getMetrics(metrics); screenWidth = metrics.widthPixels; screenHeight = metrics.heightPixels; sView = (SurfaceView) findViewById(R.id.sView); // 设置surface不需要自己的维护缓存区 sView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // 获得SurfaceView的SurfaceHolder surfaceHodler = sView.getHolder(); // 为srfaceHolder添加一个回调监听器 surfaceHodler.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceDestroyed(SurfaceHolder arg0) { // 如果camera不为null,释放摄像头 System.out.println("释放摄像头"); if (camera != null) { if (isPreview) camera.stopPreview(); camera.release(); camera = null; isPreview = false; } } @Override public void surfaceCreated(SurfaceHolder arg0) { System.out.println("打开摄像头"); // 打开摄像头 initCamera(); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { System.out.println("摄像头改变"); } }); } public void capture(View source) { sView.setVisibility(View.VISIBLE); } private void initCamera() { if (!isPreview) { // 此处默认打开后置摄像头 // 通过传入参数可以打开前置摄像头 camera = openFrontFacingCameraGingerbread(); } if (!isPreview && camera != null) { Camera.Parameters parameters = camera.getParameters(); // 设置预览照片的大小 parameters.setPreviewSize(screenWidth, screenHeight); // 设置预览照片时每秒显示多少帧的最小值和最大值 parameters.setPreviewFpsRange(4, 10); // 设置照片的格式 parameters.setPictureFormat(ImageFormat.JPEG); parameters.setPreviewSize(800, 480);//图片大小 // 设置JPG照片的质量 parameters.set("jpeg-quality", 100); // 设置照片的大小 parameters.setPictureSize(screenWidth, screenHeight); // 通过SurfaceView显示取景画面 try { camera.setPreviewDisplay(surfaceHodler); // 系统相机默认是横屏的,我们要旋转90° camera.setDisplayOrientation(90); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 开始预览 camera.startPreview(); isPreview = true; new Handler().postDelayed(new Runnable() { @Override public void run() { if (camera != null) { System.out.println("控制摄像头自动对焦后才拍摄"); // 控制摄像头自动对焦后才拍摄 //camera.autoFocus(autoFocusCallback); //关闭声音 setCameraSound(true); camera.takePicture(new Camera.ShutterCallback() { @Override public void onShutter() { // 按下快门瞬间会执行此处代码 } }, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] arg0, Camera arg1) { // 此处代码可以决定是否需要保存原始照片信息 } }, jpeg); } } }, 1000); } } private Camera openFrontFacingCameraGingerbread() { int cameraCount = 0; Camera cam = null; Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); cameraCount = Camera.getNumberOfCameras(); System.out.println("cameraCount = "+cameraCount); for (int camIdx = 0; camIdx < cameraCount; camIdx++) { Camera.getCameraInfo(camIdx, cameraInfo); if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { try { cam = Camera.open(camIdx); } catch (RuntimeException e) { Log.e("", "Camera failed to open: " + e.getLocalizedMessage()); } } } System.out.println("获取摄像头"); if (cam == null) System.out.println("摄像头获取失败"); return cam; } Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() { @Override public void onAutoFocus(boolean arg0, Camera arg1) { if (arg0) { //关闭声音 setCameraSound(true); // takePicture()方法需要传入三个监听参数 // 第一个监听器;当用户按下快门时激发该监听器 // 第二个监听器;当相机获取原始照片时激发该监听器 // 第三个监听器;当相机获取JPG照片时激发该监听器 System.out.println("拍照"); camera.takePicture(new Camera.ShutterCallback() { @Override public void onShutter() { // 按下快门瞬间会执行此处代码 } }, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] arg0, Camera arg1) { // 此处代码可以决定是否需要保存原始照片信息 } }, jpeg); new Handler().postDelayed(new Runnable() { @Override public void run() { // sView.setVisibility(View.GONE); // } }, 1000); } else { System.out.println("对焦失败,不拍照"); } } }; //创建jpeg图片回调数据对象 Camera.PictureCallback jpeg = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { // TODO Auto-generated method stub try { Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); // 创建一个位于SD卡上的文件 File file = new File(Environment.getExternalStorageDirectory() + File.separator + "aaa"); if (!file.exists()) { file.mkdir(); } file = new File(file, System.currentTimeMillis() + ".jpg"); FileOutputStream fileOutStream = null; try { fileOutStream = new FileOutputStream(file); //把位图输出到指定的文件中 bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutStream); fileOutStream.close(); } catch (IOException io) { io.printStackTrace(); } camera.stopPreview();//关闭预览 处理数据 camera.startPreview();//数据处理完后继续开始预览 bitmap.recycle();//回收bitmap空间 isPreview = true; //关闭预览框,回复声音 sView.setVisibility(View.GONE); setCameraSound(false); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; private void setCameraSound(final boolean isSound) { new Thread( new Runnable() { @Override public void run() { AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); audioManager.setStreamMute(AudioManager.STREAM_SYSTEM, isSound); } } ).start(); }}
XML
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.jin.activity.MainActivity"> <SurfaceView android:id="@+id/sView" android:layout_width="80dp" android:layout_height="100dp" android:layout_alignParentRight="true" android:visibility="gone"></SurfaceView> <Button android:id="@+id/take" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:onClick="capture" android:text="开门"></Button></RelativeLayout>
注:
经过测试发现7.0以下手机没问题,而7.0系统手机在Camera.open()出现Camera failed to open: Fail to connect to camera service,就是获取不到相机服务无法打开相机,需要手动在手机设置里面打开相机权限,即可正常使用。因此可以加一个判断:
//判断系统版本大于23,即24(7.0)和以上版本提示打开权限 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { }
阅读全文
0 0
- 自定义相机,使用前置摄像头实现自拍
- Android自定义相机(二) —— 前置摄像头
- android自定义相机 前置摄像头拍照,照片旋转180
- Android 自定义相机开发(支持前置,后置摄像头,可以自动聚焦,保存和显示图片)
- 自定义相机,用于默认打开前置相机
- Android 自定义相机摄像头
- android 如何实现前置camera自拍镜像功能
- 调用相机的前置摄像头 两点触屏缩放
- 实现自定义相机(camera的使用)
- Camera使用-实现简单的自定义相机
- 安卓手机使用前置摄像头
- 前置摄像头、后置摄像头
- 樱桃相机_自拍利器
- 【Android】自定义相机的实现(支持连续拍照、前后摄像头切换、连续对焦)
- 【Android基础】-调用前置摄像头实现的‘手机镜子’
- android-摄像头-调用前置摄像头
- [apk破解]usb webcam,修改为使用前置摄像头
- 虚拟机Linux如何使用笔记本电脑的前置摄像头
- tensorflow报错:setting an array element with a sequence
- telnet mysql时出现:is not allowed to connect to this MySQL serverConnection closed by foreign host问题的解决
- POJ 2516 Minimum Cost (最小费用最大流)
- 新开启
- Linux下如何方便下载百度网盘文件
- 自定义相机,使用前置摄像头实现自拍
- #516. 「LibreOJ β Round #2」DP 一般看规律 stl容器
- Android项目里集成Cordova详解
- synchronized 关键字 随笔
- SpringMVC:配置过程
- vim 用ctags时增加当前文件包含的boost头文件属性跳转
- ubutun查询ip地址
- matlab2c使用c++实现matlab函数系列教程-geomean函数
- Java学习路线图