600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > Android开发自定义相机 自定义拍照界面

Android开发自定义相机 自定义拍照界面

时间:2020-11-13 10:21:47

相关推荐

Android开发自定义相机 自定义拍照界面

1、目的

:开发时产品需求自己定义拍照界面,拍照处理。如下图:自定义一个拍照界面

可以看到,底部拍照按钮,和相册选择。整个界面和系统相机不一样。这时我们就要自己去开发定义自己的相机处理。

2、实现思路

写好自己需求的相机界面布局。拍照界面就相当于一个activity界面。然后调用系统API去实时获取硬件捕获到的图像用系统控件SurfaceView实时渲染出来。点击拍照,系统API提供返回原图,此时需要压缩处理,本文引入git上Luban图片压缩处理。多说一句,可异步、同步压缩,包括尺寸和存储大小的压缩。主要API:Camera。当然更建议用Camera2.本文不作描述。

3、代码实现

3.1、先重写SurfaceView,相当于一个动态显示框用作把硬件捕捉的图像实时显示,咱们相机界面的预览控件。可在自己相机界面直接引用该控件。或者动态加入布局中。

/*** Author txwang** @version V1.0* Created by txwang on /5/5.* Instruction :* @date: -05-05 11:04**/public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {private SurfaceHolder mHolder;private Camera mCamera;public CameraPreview(Context context, Camera camera) {super(context);//初始化Camera对象mCamera = camera;//得到SurfaceHolder对象mHolder = getHolder();//添加回调,得到Surface的三个声明周期方法mHolder.addCallback(this);// deprecated setting, but required on Android versions prior to 3.0mHolder.setType(SurfaceHolder.SURFACE_TYPE_HARDWARE);}@Overridepublic void surfaceCreated(SurfaceHolder holder) {try {//设置预览方向z'z'zmCamera.setDisplayOrientation(90);//把这个预览效果展示在SurfaceView上面mCamera.setPreviewDisplay(holder);//开启预览效果mCamera.startPreview();} catch (IOException e) {// Log.d(TAG, "Error setting camera preview: " + e.getMessage());}}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {if (holder.getSurface() == null) {return;}//停止预览效果mCamera.stopPreview();//重新设置预览效果try {mCamera.setPreviewDisplay(mHolder);} catch (IOException e) {e.printStackTrace();}mCamera.startPreview();}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {}}

3.2、接下来实例化系统相机API,初始化设置

setPictureFormat设置拍照后图片尺寸,可防止预览图像清晰,拍出来的照片模糊情况,直接获取当前手机分辨率设置就行

setPreviewSize设置预览图像大小,在你预览控件CameraPreview显示效果。如果需要手动点击对焦,就不必设置自动对焦。

mCamera = Camera.open(); //初始化 Camera对象CameraPreview mPreview = new CameraPreview(this, mCamera);LinearLayout camera_preview = (LinearLayout) findViewById(R.id.camera_preview);camera_preview.addView(mPreview);//得到照相机的参数Camera.Parameters parameters = mCamera.getParameters();//图片的格式parameters.setPictureFormat(ImageFormat.JPEG);// //预览的大小是多少// parameters.setPreviewSize(camera_preview.getMeasuredWidth(), camera_preview.getMeasuredHeight());//设置对焦模式,自动对焦parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);mCamera.setParameters(parameters);

mCamera.takePicture(null, null, mPictureCallback);

完整相机界面代码

/*** wtx* 相机界面*/public class CameraActivity extends BaseActivity {private Camera mCamera;private boolean isAblum;@BindView(R.id.tv_img)TextView imgTV;@Overrideprotected BasePresenter createPresenter() {return null;}//获取照片中的接口回调Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {@Overridepublic void onPictureTaken(byte[] data, Camera camera) {//这里就是拍照成功后返回照片的地方,注意,返回的是原图,可能几兆十几兆大,需要压缩处理FileOutputStream fos = null;String path = Environment.getExternalStorageDirectory().getPath();String mFilePath = path + File.separator + "tt001.png";//文件Long currentTimeMillis = DateUtils.getCurrentTimeMillis();try {File jpgFile = new File(mFilePath);FileOutputStream outputStream = new FileOutputStream(jpgFile); // 文件输出流outputStream.write(data); // 写入sd卡中outputStream.close(); // 关闭输出流//fos.write(data);long l1 = DateUtils.getCurrentTimeMillis() - currentTimeMillis;Long d = DateUtils.getCurrentTimeMillis();Logger.e("图片存储时间--"+ l1);Luban.with(CameraActivity.this).load(jpgFile)// 传人要压缩的图片列表.ignoreBy(200) // 忽略不压缩图片的大小.setTargetDir(path) // 设置压缩后文件存储位置.setCompressListener(new OnCompressListener() { //设置回调@Overridepublic void onStart() {}@Overridepublic void onSuccess(File file) {long l2 = DateUtils.getCurrentTimeMillis() - d;Logger.e("图片压缩时间--"+ l2);EventBus.getDefault().post(new EventMessage<String>(EventBusTag.PIC_SUCCESS,file.getPath()));finish();}@Overridepublic void onError(Throwable e) {}}).launch(); //启动压缩} catch (IOException e) {e.printStackTrace();} finally {//实现连续拍多张的效果//mCamera.startPreview();if (fos != null) {try {fos.close();} catch (IOException e) {e.printStackTrace();}}}}};@Overrideprotected void onDestroy() {super.onDestroy();if (mCamera != null) {mCamera.stopPreview();mCamera.setPreviewCallback(null);mCamera.release();mCamera = null;}}@Overrideprotected void initView() {mCamera = Camera.open(); //初始化 Camera对象CameraPreview mPreview = new CameraPreview(this, mCamera);LinearLayout camera_preview = (LinearLayout) findViewById(R.id.camera_preview);camera_preview.addView(mPreview);//得到照相机的参数Camera.Parameters parameters = mCamera.getParameters();//图片的格式parameters.setPictureFormat(ImageFormat.JPEG);// //预览的大小是多少// parameters.setPreviewSize(camera_preview.getMeasuredWidth(), camera_preview.getMeasuredHeight());//设置对焦模式,自动对焦parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);mCamera.setParameters(parameters);findViewById(R.id.tv_pic).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//获取照片mCamera.takePicture(null, null, mPictureCallback);////对焦成功后,自动拍照//mCamera.autoFocus(new Camera.AutoFocusCallback() {//@Override//public void onAutoFocus(boolean success, Camera camera) {// if (success) {//// }//}//});}});}@Overrideprotected void execute() {imgTV.setVisibility(isAblum ? View.VISIBLE:View.GONE);}@Overrideprotected boolean getData(Intent intent) {isAblum = intent.getBooleanExtra(IntentCode.IS_ABLUM,false);return true;}@Overrideprotected int getLayoutId() {return R.layout.activity_camera;}@OnClick({R.id.tv_img,R.id.tv_back})public void onViewClick(View view){switch (view.getId()){case R.id.tv_img://相机界面跳转相册,这里可以直接删除,自己选用第三方相册去展示jumpToMatisse(CameraActivity.this, 1,PicMgr.REQUEST_CODE_FINSH);break;case R.id.tv_back:finish();break;}}private void jumpToMatisse(BaseActivity activity, final int count, int resultCode) {SelectionCreator selectionCreator = Matisse.from(activity).choose(MimeType.ofAll());selectionCreator.capture(false).countable(true).maxSelectable(count).addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K)).gridExpectedSize(activity.getResources().getDimensionPixelSize(R.dimen.px300)).restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED).captureStrategy(new CaptureStrategy(true, activity.getApplicationContext().getPackageName() + ".fileprovider")).thumbnailScale(0.85f).theme(R.style.Matisse_Zhihu)//.imageEngine(new GlideEngine()).imageEngine(new Glide4Engine()).setOnSelectedListener(new OnSelectedListener() {@Overridepublic void onSelected(@NonNull List<Uri> uriList, @NonNull List<String> pathList) {Log.e("onSelected", "onSelected: pathList=" + pathList);}}).originalEnable(true).maxOriginalSize(10).forResult(resultCode);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == PicMgr.REQUEST_CODE_FINSH && resultCode == RESULT_OK) {setResult(Activity.RESULT_OK,data);finish();}}

4、备注

相机界面布局就不多写了,一个小demo,很简单的布局,大体实现思路吧。很简单粗略的实现,如果需要实现更复杂的功能,可以根据自己的实际需求去查相应的api。比如,曝光、打开闪光灯,聚焦。甚至图像处理简单美颜等等。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。