国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義Camera實現拍照功能

2019-10-22 18:10:26
字體:
來源:轉載
供稿:網友

本文記錄了用自定義Camera實現的簡單拍照功能。

Camera類在5.0以后不推薦使用了,取而代之的是android.hardware.camera2包下的類,本文使用Camera。 
我們首先自定義一個View去繼承SurfaceView:

public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Camera.AutoFocusCallback { private SurfaceHolder mHolder; private Camera mCamera; private static final int ORIENTATION = 90; private int mScreenWidth; private int mScreenHeight; private boolean isOpen; public CameraSurfaceView(Context context, AttributeSet attrs) {  super(context, attrs);  getScreenMatrix(context);  mHolder = getHolder();  mHolder.addCallback(this);  mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } private void getScreenMatrix(Context context) {  WindowManager WM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);  DisplayMetrics outMetrics = new DisplayMetrics();  WM.getDefaultDisplay().getMetrics(outMetrics);  mScreenWidth = outMetrics.widthPixels;  mScreenHeight = outMetrics.heightPixels; } public void takePicture(Camera.ShutterCallback mShutterCallback, Camera.PictureCallback rawPictureCallback, Camera.PictureCallback jpegPictureCallback) {  if (mCamera != null)   mCamera.takePicture(mShutterCallback, rawPictureCallback, jpegPictureCallback); } public void startPreview() {  mCamera.startPreview(); } @Override public void surfaceCreated(SurfaceHolder holder) {  if (!checkCameraHardware(getContext()))   return;  if (mCamera == null) {   isOpen = safeCameraOpen(Camera.CameraInfo.CAMERA_FACING_BACK);  }  if (!isOpen) {   return;  }  mCamera.setDisplayOrientation(ORIENTATION);  try {   mCamera.setPreviewDisplay(holder);  } catch (IOException e) {   e.printStackTrace();  } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  if (mCamera != null) {   setCameraParams(mScreenWidth, mScreenHeight);   mCamera.startPreview();  } } @Override public void surfaceDestroyed(SurfaceHolder holder) {  releaseCameraAndPreview(); } private boolean safeCameraOpen(int id) {  boolean qOpened = false;  try {   releaseCameraAndPreview();   mCamera = Camera.open(id);   qOpened = (mCamera != null);  } catch (Exception e) {   e.printStackTrace();  }  return qOpened; } private void releaseCameraAndPreview() {  if (mCamera != null) {   mCamera.stopPreview();   mCamera.release();   mCamera = null;  } } private boolean checkCameraHardware(Context context) {  if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {   return true;  } else {   return false;  } } @Override public void onAutoFocus(boolean success, Camera camera) { } private void setCameraParams(int width, int height) {  Camera.Parameters parameters = mCamera.getParameters();  // 獲取攝像頭支持的PictureSize列表  List<Camera.Size> pictureSizeList = parameters.getSupportedPictureSizes();  /**從列表中選取合適的分辨率*/  Camera.Size picSize = getProperSize(pictureSizeList, ((float) height / width));  if (null == picSize) {   picSize = parameters.getPictureSize();  }  // 根據選出的PictureSize重新設置SurfaceView大小  float w = picSize.width;  float h = picSize.height;  parameters.setPictureSize(picSize.width, picSize.height);  this.setLayoutParams(new RelativeLayout.LayoutParams((int) (height * (h / w)), height));  // 獲取攝像頭支持的PreviewSize列表  List<Camera.Size> previewSizeList = parameters.getSupportedPreviewSizes();  Camera.Size preSize = getProperSize(previewSizeList, ((float) height) / width);  if (null != preSize) {   parameters.setPreviewSize(preSize.width, preSize.height);  }  parameters.setJpegQuality(100); // 設置照片質量  if (parameters.getSupportedFocusModes().contains(android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {   parameters.setFocusMode(android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);// 連續對焦模式  }  mCamera.setDisplayOrientation(90);// 設置PreviewDisplay的方向,效果就是將捕獲的畫面旋轉多少度顯示  mCamera.setParameters(parameters); } /**  * 選取合適的分辨率  */ private Camera.Size getProperSize(List<Camera.Size> pictureSizeList, float screenRatio) {  Camera.Size result = null;  for (Camera.Size size : pictureSizeList) {   float currentRatio = ((float) size.width) / size.height;   if (currentRatio - screenRatio == 0) {    result = size;    break;   }  }  if (null == result) {   for (Camera.Size size : pictureSizeList) {    float curRatio = ((float) size.width) / size.height;    if (curRatio == 4f / 3) {// 默認w:h = 4:3     result = size;     break;    }   }  }  return result; }}

代碼沒什么難度,在View創建的時候完成Camera的初始化,然后對Camera進行參數的設置(圖片尺寸,質量之類的),最后別忘了在View銷毀的時候對資源進行釋放。

控件定義完了之后我們就要去使用它,在布局文件中添加就OK:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" > <com.padoon.cameratest.CameraSurfaceView  android:id="@+id/sv_camera"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:layout_weight="4"/> <ImageView  android:id="@+id/img_take_photo"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignParentBottom="true"  android:layout_alignParentRight="true"  android:layout_gravity="bottom"  android:layout_marginBottom="10dp"  android:layout_marginRight="10dp"  android:src="@mipmap/icon_camera"/></RelativeLayout>

然后在Activity中去完成拍照功能:

 

public class CameraActivity extends AppCompatActivity { private boolean isClick = true; private static final String PATH_IMAGES = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "easy_check"; private CameraSurfaceView mCameraSurfaceView; //拍照快門的回調 private Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback() {  @Override  public void onShutter() {  } }; //拍照完成之后返回原始數據的回調 private Camera.PictureCallback rawPictureCallback = new Camera.PictureCallback() {  @Override  public void onPictureTaken(byte[] data, Camera camera) {  } }; //拍照完成之后返回壓縮數據的回調 private Camera.PictureCallback jpegPictureCallback = new Camera.PictureCallback() {  @Override  public void onPictureTaken(byte[] data, Camera camera) {   mCameraSurfaceView.startPreview();   saveFile(data);   Toast.makeText(CameraActivity.this, "拍照成功", Toast.LENGTH_SHORT).show();   isClick = true;  } }; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  ImageView img_take_photo = (ImageView) findViewById(R.id.img_take_photo);  mCameraSurfaceView = (CameraSurfaceView) findViewById(R.id.sv_camera);  img_take_photo.setOnClickListener(new View.OnClickListener() {   @Override   public void onClick(View v) {    takePhoto();   }  }); } public void takePhoto() {  if (isClick) {   isClick = false;   mCameraSurfaceView.takePicture(mShutterCallback, rawPictureCallback, jpegPictureCallback);  } } //保存圖片到硬盤 public void saveFile(byte[] data) {  String fileName = UUID.randomUUID().toString() + ".jpg";  FileOutputStream outputStream = null;  try {   File file = new File(PATH_IMAGES);   if (!file.exists()) {    file.mkdirs();   }   outputStream = new FileOutputStream(PATH_IMAGES + File.separator + fileName);   BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);   bufferedOutputStream.write(data, 0, data.length);  } catch (Exception e) {   e.printStackTrace();  } finally {   try {    outputStream.close();   } catch (IOException e) {    e.printStackTrace();   }  } }}

最后記得添加拍照跟磁盤操作權限:

<uses-permission android:name="android.permission.CAMERA"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

到這一個非常簡單的拍照Demo就完成了,只能當做Demo使用,離開發正式使用還有一段的距離,再次特地記錄一下。

下載:源碼

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 平舆县| 平罗县| 凤凰县| 靖远县| 九江县| 大渡口区| 浠水县| 巴林右旗| 庆云县| 静乐县| 佳木斯市| 新龙县| 华亭县| 扶风县| 油尖旺区| 天峨县| 海伦市| 宝兴县| 孝昌县| 嘉义市| 上饶县| 会理县| 福贡县| 晋城| 珠海市| 黔西县| 家居| 靖远县| 德令哈市| 阿拉善盟| 射洪县| 抚州市| 兴安盟| 龙陵县| 土默特左旗| 沙田区| 山东省| 岗巴县| 德化县| 鹤壁市| 清丰县|