
Android摄像头自定义相机拍照流程
发布日期:2021-05-08 18:11:36
浏览次数:19
分类:原创文章
本文共 8851 字,大约阅读时间需要 29 分钟。
最近完善了一下相机的app,除了拍照功能,现在增加了开启闪光灯,切换前后置摄像头,相册功能,图片删除,图片分享功能,设置照片大小,以及照片的质量,视频方面,有录制视频,设置视频录制大小,本应用拍摄的视频预览,以及视频播放界面。
下面是应用的一些截图,由于项目是自己开发,没有美工优化界面,所以界面比较难看,另外附上github的地址:代码方面并没有做过多的优化,只是供新人学习相机开发流程,大神勿喷:
github : https://github.com/jingxiongdi/CameraJXD
应用部分界面截图:
记录一下Android摄像头拍照的问题:
前言:权限问题,一定别忘记
<uses-permission android:name="android.permission.FLASHLIGHT" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
1.摄像头开启:0为后置,1为前置
判断是否有前后置摄像头
由于getNumberOfCameras以及getCameraInfo均为API 9 引入,所以方法只适用于2.3及其以上
private boolean checkCamera(final int facing) { if (getSdkVersion() < Build.VERSION_CODES.GINGERBREAD) { return false; } final int cameraCount = Camera.getNumberOfCameras(); CameraInfo info = new CameraInfo(); for (int i = 0; i < cameraCount; i++) { Camera.getCameraInfo(i, info); if (facing == info.facing) { return true; } } return false; } public static boolean hasBackFacingCamera() { final int CAMERA_FACING_BACK = 0; return checkCameraFacing(CAMERA_FACING_BACK); } public static boolean hasFrontFacingCamera() { final int CAMERA_FACING_FRONT = 1; return checkCameraFacing(CAMERA_FACING_FRONT); } public static int getSdkVersion() { return android.os.Build.VERSION.SDK_INT; }
2.开启摄像头 0为后置,1为前置mCamera = Camera.open(0);
3.设置预览旋转public 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 = 0; 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 ); }
4.获取和设置相机参数:
try { Camera.Parameters parameters = mCamera.getParameters();// List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();// for(int i = 0; i<supportedPreviewSizes.size();i++)// {// Log.d("jxd","supportedPreviewSizes : "+supportedPreviewSizes.get(i).width +" * "+supportedPreviewSizes.get(i).height);// } List<Camera.Size> supportedVideoSize = parameters.getSupportedVideoSizes(); for(int i = 0; i<supportedVideoSize.size();i++) { Log.d("jxd","supportedVideoSize : "+supportedVideoSize.get(i).width +" * "+supportedVideoSize.get(i).height); }// List<Camera.Size> supportedJpegThumbnailSizes = parameters.getSupportedJpegThumbnailSizes();// for(int i = 0; i<supportedJpegThumbnailSizes.size();i++)// {// Log.d("jxd","supportedJpegThumbnailSizes : "+supportedJpegThumbnailSizes.get(i).width +" * "+supportedJpegThumbnailSizes.get(i).height);// } if(!Hawk.contains(Contants.PHOTO_SIZE)) { List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes(); for(int i = 0; i<supportedPictureSizes.size();i++) { Log.d("jxd","supportedPictureSizes : "+supportedPictureSizes.get(i).width +" * "+supportedPictureSizes.get(i).height); } Hawk.put(Contants.PHOTO_SIZE,supportedPictureSizes); }// List<int[]> supportedPreviewFpsRange = parameters.getSupportedPreviewFpsRange();// for(int i = 0; i<supportedPreviewFpsRange.size();i++)// {// Log.d("jxd","supportedPreviewFpsRange : =============== "+supportedPreviewFpsRange.get(i).length);// for(int k = 0;k<supportedPreviewFpsRange.get(i).length;k++)// {// Log.d("jxd","supportedPreviewFpsRange : "+supportedPreviewFpsRange.get(i)[k]);// }// } //设置预览照片的大小 // parameters.setPreviewFpsRange(viewWidth, viewHeight); //设置相机预览照片帧数 // parameters.setPreviewFpsRange(4, 10); //设置图片格式 parameters.setPictureFormat(ImageFormat.JPEG); //设置图片的质量 int pos = 100; if(Hawk.contains(Contants.CURRENT_PHOTO_QUALITY)) { String p = Hawk.get(Contants.CURRENT_PHOTO_QUALITY); try { pos = Integer.parseInt(p); } catch (Exception e) { e.printStackTrace(); } Log.d("jxd","jpeg CURRENT_PHOTO_QUALITY : "+pos); } parameters.set("jpeg-quality", pos); //设置照片的大小 Camera.Size size = null; if(Hawk.contains(Contants.CURRENT_PHOTO_SIZE)) { int p = Hawk.get(Contants.CURRENT_PHOTO_SIZE); size = parameters.getSupportedPictureSizes().get(p); Log.d("jxd","jpeg CURRENT_PHOTO_SIZE : "+size.width+" * "+size.height); } if(size != null) { parameters.setPictureSize(size.width, size.height); } else { parameters.setPictureSize(viewWidth, viewHeight); } parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); mCamera.setParameters(parameters);
5.开启预览
//通过SurfaceView显示预览 mCamera.setPreviewDisplay(mHolder); //开始预览 mCamera.startPreview();
6.点击拍照以及设置图片旋转
private void takePhoto() { if (mCamera == null ) { return; } // mCamera.stopPreview(); Log.d("jxd","takePhoto "); mCamera.takePicture(null, null, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { new SavePictureTask().execute(data); // camera.startPreview(); } }); } // save pic class SavePictureTask extends AsyncTask<byte[], String, String> { @Override protected String doInBackground(byte[]... params) { String fname = DateFormat.format("yyyyMMddhhmmss", new Date()).toString()+".jpg"; Log.i("jxd", "fname="+fname+";dir="+ Environment.getExternalStorageDirectory()); //picture = new File(Environment.getExternalStorageDirectory(),fname);// create file File picture = new File(Environment.getExternalStorageDirectory()+"/CameraJXD/"+fname); try { FileOutputStream fos = new FileOutputStream(picture.getPath()); // Get file output stream fos.write(params[0]); // Written to the file fos.close(); } catch (Exception e) { e.printStackTrace(); } /** * 解决照片旋转90度的问题 */ Bitmap bitmap = BitmapFactory.decodeFile(picture.getPath()); Matrix matrix = new Matrix(); matrix.postRotate(90); Bitmap dstbmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); FileOutputStream fOut = null; try { fOut = new FileOutputStream(Environment.getExternalStorageDirectory()+"/CameraJXD/"+"rotate"+fname); dstbmp.compress(Bitmap.CompressFormat.JPEG, 90, fOut); fOut.flush(); fOut.close(); } catch (Exception e) { } picture.delete(); return null; } }
7.自定义相机就完成了,可以随意设置照片的大小和质量,这也是我一直以来想要的功能,之前一直没有去弄这个,网上又没有找到现成的可以随意定义这么多参数的Android相机,所以自己弄一个玩玩。发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2025年04月17日 14时20分04秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
基础练习 十六进制转八进制(模拟)
2021-05-09
L - Large Division (大数, 同余)
2021-05-09
39. Combination Sum
2021-05-09
41. First Missing Positive
2021-05-09
80. Remove Duplicates from Sorted Array II
2021-05-09
83. Remove Duplicates from Sorted List
2021-05-09
410. Split Array Largest Sum
2021-05-09
开源项目在闲鱼、b 站上被倒卖?这是什么骚操作?
2021-05-09
Vue3发布半年我不学,摸鱼爽歪歪,哎~就是玩儿
2021-05-09
《实战java高并发程序设计》源码整理及读书笔记
2021-05-09
Java开源博客My-Blog(SpringBoot+Docker)系列文章
2021-05-09
程序员视角:鹿晗公布恋情是如何把微博搞炸的?
2021-05-09
【JavaScript】动态原型模式创建对象 ||为何不能用字面量创建原型对象?
2021-05-09
Linux应用-线程操作
2021-05-09
多态体验,和探索爷爷类指针的多态性
2021-05-09
系统编程-进程间通信-无名管道
2021-05-09
记2020年初对SimpleGUI源码的阅读成果
2021-05-09
C语言实现面向对象方法学的GLib、GObject-初体验
2021-05-09