Android 自定义Camera拍照

xiaoxiao2021-02-28  48

#

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> 1234567891011

初始化控件:

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 == ){ mCamera = Camera.open(); } mCamera.takePicture(,,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 != ) { 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 != ) { 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 != && !supportedPictureSizes.isEmpty()) { int screenSize = screenHeight * screenWidth; Camera.Size picSize = ; for (Camera.Size size : supportedPictureSizes) { int value = size.height * size.width; if (value <= screenSize) { if (picSize == ) { picSize = size; } else { // 取最接近屏幕尺寸的 if (value > picSize.width * picSize.height) { picSize = size; } } } } if (picSize == ) { 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 != ) { mCamera.setPreviewCallback(); mCamera.stopPreview(); mCamera.release(); mCamera = ; } } 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130

调用相机的拍摄功能:

点击拍照调用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 = ; 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(); } 12345678910111213141516171819202122232425262728293031

接下来要说的就是我们上面说到的保存图片被旋转的问题:

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 == ){ bitmap = bm; } if(bm != bitmap){ bm.recycle(); } return bitmap; } @Override public void onPause(){ super.onPause(); if(camera != ){ if(isPrevew){ camera.stopPreview(); camera.release(); camera= ; isPreView= false; } } } @Override protected void onResume() { super.onResume(); openCamera(); } 12345678910111213141516171819202122232425262728293031323334353637

*#额外要说明的是,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); } 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css"> </div>
转载请注明原文地址: https://www.6miu.com/read-2613925.html

最新回复(0)