Android自定义Camera实现拍照小功能
时间:2022-11-25 10:41:19|栏目:Android代码|点击: 次
本文实例为大家分享了Android自定义Camera实现拍照的具体代码,供大家参考,具体内容如下
本篇文章就项目开发遇到问题记录下;
1.拍照图片被压缩问题
2.拍照图片被旋转问题
首先实现一个自定义拍照功能。
自定义布局
<FrameLayout android:layout_below="@id/toolbar_layout" android:layout_width="match_parent" android:layout_height="match_parent" > <SurfaceView android:id="@+id/surface" android:layout_width="match_parent" android:layout_height="match_parent" android:keepScreenOn="true"/> </FrameLayout>
初始化控件:
surfaceView = (SurfaceView) findViewById(R.id.surface); holder = surfaceView.getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); btn.setOnCLickListener(new OnClickLister(View v){ if(mCamera == null){ mCamera = Camera.open(); } mCamera.takePicture(null,null,this); }); @Override public void surfaceCreated(SurfaceHolder surfaceHolder) { initStartCamera(surfaceHolder); } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) { mCamera.autoFocus(new Camera.AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { isAutoFocus = success; initCameraParams(); mCamera.cancelAutoFocus(); mCamera.startPreview(); } }); } @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) { // 当holder被回收时 释放硬件 // releaseCamera(); } @Override protected void onPause() { super.onPause(); releaseCameraSource(); } @Override protected void onResume() { super.onResume(); // TODO: 看看退出到其他页面是否有黑屏现象 if (surfaceView != null) { surfaceView.postDelayed(new Runnable() { @Override public void run() { initCameraParams(); } }, 50); } } private void initStartCamera(SurfaceHolder surfaceHolder) { try { mCamera = Camera.open(); mCamera.setDisplayOrientation(90); mCamera.setPreviewDisplay(surfaceHolder); mCamera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } private void initCameraParams() { if (mCamera != null) { Camera.Parameters parameters = mCamera.getParameters(); parameters.setPictureFormat(ImageFormat.JPEG); parameters.setJpegQuality(90); List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes(); WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE); Display display = manager.getDefaultDisplay(); Point point = new Point(); display.getSize(point); int screenWidth = point.x; int screenHeight = point.y; // 找到适合的图片的尺寸 if (supportedPictureSizes != null && !supportedPictureSizes.isEmpty()) { int screenSize = screenHeight * screenWidth; Camera.Size picSize = null; for (Camera.Size size : supportedPictureSizes) { int value = size.height * size.width; if (value <= screenSize) { if (picSize == null) { picSize = size; } else { // 取最接近屏幕尺寸的 if (value > picSize.width * picSize.height) { picSize = size; } } } } if (picSize == null) { picSize = supportedPictureSizes.get(0); } parameters.setPictureSize(picSize.width, picSize.height); } // 设置对焦模式 List<String> supportedFocusModes = parameters.getSupportedFocusModes(); if (supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { // 快速对焦 parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); } else { parameters.setFocusMode(Camera.Parameters.FLASH_MODE_AUTO); } try { mCamera.setParameters(parameters); mCamera.startPreview(); } catch (Exception e) { e.printStackTrace(); } } } private void releaseCameraSource() { if (mCamera != null) { mCamera.setPreviewCallback(null); mCamera.stopPreview(); mCamera.release(); mCamera = null; } }
调用相机的拍摄功能:
点击拍照调用camera.takePicture(null,null,this);
获取拍照回调回来的图片数据
public void onPictureTaken(final byte[] bytes,final Camera camera){ // 拍照回掉回来的 图片数据。 final String filePath = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/"; final String picturePath = System.currentTimeMillis() + ".jpg"; final File file = new File(filePath, picturePath); new Thread(new Runnable() { @Override public void run() { Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); bitmap = rotateBitmapByDegree(bitmap, 90); BufferedOutputStream bos = null; try { //防止拍照保存图片被压缩 bos = new BufferedOutputStream(new FileOutputStream(file)); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos); bos.flush(); bos.close(); bitmap.recycle(); Intent intent = new Intent(TakePhotoActivity.this,TPreViewPicActivity.class); intent.putExtra("filePath",filePath); intent.putExtra("picturePath",picturePath); startActivityForResult(intent,102); } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } } }).start(); }
接下来要说的就是我们上面说到的保存图片被旋转的问题:
public Bitmap rotateBitmapByDegree(Bitmap bm,int degree){ Bitmap bitmap ; Matrix matrix = new Matrix(); matrix.postRotate(degree); try{ bitmap = Bitmap.createBitmap(bm,0,bm.getWidth,bm.getHeight,matrix,true); }catch(OutOfMemoryError e){ e.printStackTrace(); } if(bitmap == null){ bitmap = bm; } if(bm != bitmap){ bm.recycle(); } return bitmap; } @Override public void onPause(){ super.onPause(); if(camera != null){ if(isPrevew){ camera.stopPreview(); camera.release(); camera= null; isPreView= false; } } } @Override protected void onResume() { super.onResume(); openCamera(); }
*#额外要说明的是,android 6.0权限问题,可能会导致首次进入拍照界面黑屏,解决方案在拍照界面之前请求权限;
最后附上请求权限代码:
public void checkPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[]{Manifest.permission.CAMERA} , new TCallPhoneTool.PermissionListener() { @Override public void onGranted() { // openCamera(); } @Override public void onRefused(List<String> deniedPermissions) { showMissingPermissionDialog(); } }); } else { // openCamera(); } } TCallPhoneTool.PermissionListener mListener ; final int REQUEST_CODE_STORAGE = 131; public void requestPermissions(String[] permissions, TCallPhoneTool.PermissionListener listener) { List<String> deniedPermissions = new ArrayList<>() ; mListener = listener ; for (String permission : permissions) { if (ContextCompat.checkSelfPermission(this,permission) == PackageManager.PERMISSION_DENIED) { deniedPermissions.add(permission); } } if (deniedPermissions.size() > 0) { ActivityCompat.requestPermissions(this,deniedPermissions.toArray(new String[deniedPermissions.size()]),REQUEST_CODE_STORAGE); } else { mListener.onGranted(); } } public void showMissingPermissionDialog() { android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(this); builder.setTitle(getString(com.to8to.baselib.R.string.tip_permision_miss)); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }); builder.setPositiveButton("设置", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { startAppSetting(); } }); builder.setCancelable(false); builder.show(); public void startAppSetting() { Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse("package:" + this.getPackageName())); startActivity(intent); }