Android自定義Camera實現(xiàn)拍照小功能
本文實例為大家分享了Android自定義Camera實現(xiàn)拍照的具體代碼,供大家參考,具體內(nèi)容如下
本篇文章就項目開發(fā)遇到問題記錄下;
1.拍照圖片被壓縮問題
2.拍照圖片被旋轉問題
首先實現(xiàn)一個自定義拍照功能。
自定義布局
<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: ?看看退出到其他頁面是否有黑屏現(xiàn)象 ? ? ? ? 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; ? ? ? ? } ? ? }
調(diào)用相機的拍攝功能:
點擊拍照調(diào)用camera.takePicture(null,null,this);
獲取拍照回調(diào)回來的圖片數(shù)據(jù)
public void onPictureTaken(final byte[] bytes,final Camera camera){ ? ?// 拍照回掉回來的 圖片數(shù)據(jù)。 ? ? ? ? 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); ? ? }
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
使用Fragment來處理Andoird app的UI布局的實例分享
這篇文章主要介紹了使用Fragment來處理Andoird appUI布局的實例分享,Fragment的出現(xiàn)緩解了代碼依賴于Activity而造成的臃腫狀況,需要的朋友可以參考下2016-02-02Android ScrollView無法填充滿屏幕的解決辦法
這篇文章主要介紹了Android ScrollView無法填充滿屏幕的解決辦法的相關資料,這里提供實例和解決辦法,需要的朋友可以參考下2017-07-07Android實現(xiàn)可收縮和擴展的TextView
這篇文章主要為大家詳細介紹了Android實現(xiàn)可收縮和擴展的TextView,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03Android WebView userAgent 設置為桌面UA實例
這篇文章主要介紹了Android WebView userAgent 設置為桌面UA實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03Android實現(xiàn)獲取未接來電和未讀短信數(shù)量的方法
這篇文章主要介紹了Android實現(xiàn)獲取未接來電和未讀短信數(shù)量的方法,是Android程序開發(fā)中非常常見的重要功能,需要的朋友可以參考下2014-08-08