android 自定義相機Camera
阿新 • • 發佈:2019-01-27
專案中,有時系統的相機不能滿足我們的需求,例如:實現美圖,這樣就需要我們進行自定義相機,滿足我們的特殊需求。Android給我們提供了Camera API,可以進行相機的私人訂製。在Android5以後有提供了Camera2 API,廢除了Camera API。但Camera仍舊可以使用,Camera2使用起來感覺比Camera要複雜些,Camera2功能要強於Camera,也是google提倡使用的。Camera已經基本可以滿足需求了,今天我們就要看一下Camera的使用,下一篇我們會講到Camera2的使用。
一、獲取Camera
camera=Camera.open();二、與SurfaceView進行關聯(SurfaceView進行影象繪製
sfh=sfv.getHolder(); sfh.addCallback(new SurfaceHolder.Callback() { //建立 @Override public void surfaceCreated(SurfaceHolder holder) { //開始進行圖片的預覽 startPreview(); } //改變 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { //停止舊的預覽,開啟新的預覽 camera三、進行預覽.stopPreview(); startPreview(); } //釋放 @Override public void surfaceDestroyed(SurfaceHolder holder) { //停止預覽,釋放資源 stopCamera(); } });
/** * 相機預覽*/ private void startPreview(){ try { //相機與SurfaceView進行繫結 camera.setPreviewDisplay(sfh); //預覽的圖片旋轉 camera.setDisplayOrientation(90); camera.startPreview(); } catch (IOException e) { e.printStackTrace(); } }
四、拍照
btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //設定相機的各種引數 Camera.Parameters parameters=camera.getParameters(); //對焦的方式 parameters.setFocusMode(Camera.Parameters.ANTIBANDING_AUTO); //照片的型別 parameters.setPictureFormat(ImageFormat.JPEG); //對焦監聽 camera.autoFocus(new Camera.AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { //對焦成功 if(success){ camera.takePicture(null,null,cameraCallBack); }else{ Toast.makeText(MainActivity.this,"對焦失敗!",Toast.LENGTH_SHORT).show(); } } }); } });五、處理拍照圖片,進行存到本地相簿,和本頁面預覽
/** * 拍照成功回撥函式*/ private Camera.PictureCallback cameraCallBack=new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { startPreview(); //先驗證手機是否有sdcard String status= Environment.getExternalStorageState(); if(!status.equals(Environment.MEDIA_MOUNTED)) { Toast.makeText(getApplicationContext(),"你的sd卡不可用。",Toast.LENGTH_SHORT).show(); return; } //大部分手機拍照都是存到這個路徑 String filePath=Environment.getExternalStorageDirectory().getPath()+"/DCIM/Camera/"; String picturePath=System.currentTimeMillis()+".jpg"; File file=new File(filePath,picturePath); try{ //存到本地相簿 FileOutputStream fileOutputStream=new FileOutputStream(file); fileOutputStream.write(data); fileOutputStream.close(); //顯示圖片 BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options); iv.setImageBitmap(bitmap); }catch (FileNotFoundException e){ e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } } };
六、資源的釋放
/** * 停止拍照釋放資源*/ private void stopCamera(){ if(camera!=null){ camera.stopPreview(); camera.release(); camera=null; } }
放上activity程式碼:
package com.sunshanglei.camera.customcamera; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.ImageFormat; import android.hardware.Camera; import android.os.Environment; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * use 自定義相機Camera * author 孫尚磊 * create time 2017-4-26 */ public class MainActivity extends AppCompatActivity { private SurfaceView sfv; private ImageView iv; private Button btn; private Camera camera=null; private SurfaceHolder sfh; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sfv= (SurfaceView) findViewById(R.id.sfv); iv= (ImageView) findViewById(R.id.iv); btn= (Button) findViewById(R.id.btn); camera=Camera.open(); sfh=sfv.getHolder(); sfh.addCallback(new SurfaceHolder.Callback() { //建立 @Override public void surfaceCreated(SurfaceHolder holder) { //開始進行圖片的預覽 startPreview(); } //改變 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { //停止舊的預覽,開啟新的預覽 camera.stopPreview(); startPreview(); } //釋放 @Override public void surfaceDestroyed(SurfaceHolder holder) { //停止預覽,釋放資源 stopCamera(); } }); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //設定相機的各種引數 Camera.Parameters parameters=camera.getParameters(); //對焦的方式 parameters.setFocusMode(Camera.Parameters.ANTIBANDING_AUTO); //照片的型別 parameters.setPictureFormat(ImageFormat.JPEG); //對焦監聽 camera.autoFocus(new Camera.AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { //對焦成功 if(success){ camera.takePicture(null,null,cameraCallBack); }else{ Toast.makeText(MainActivity.this,"對焦失敗!",Toast.LENGTH_SHORT).show(); } } }); } }); } /** * 拍照成功回撥函式*/ private Camera.PictureCallback cameraCallBack=new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { startPreview(); //先驗證手機是否有sdcard String status= Environment.getExternalStorageState(); if(!status.equals(Environment.MEDIA_MOUNTED)) { Toast.makeText(getApplicationContext(),"你的sd卡不可用。",Toast.LENGTH_SHORT).show(); return; } //大部分手機拍照都是存到這個路徑 String filePath=Environment.getExternalStorageDirectory().getPath()+"/DCIM/Camera/"; String picturePath=System.currentTimeMillis()+".jpg"; File file=new File(filePath,picturePath); try{ //存到本地相簿 FileOutputStream fileOutputStream=new FileOutputStream(file); fileOutputStream.write(data); fileOutputStream.close(); //顯示圖片 BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options); iv.setImageBitmap(bitmap); }catch (FileNotFoundException e){ e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } } }; @Override protected void onResume() { super.onResume(); if(camera==null){ camera=Camera.open(); if(sfh!=null){ startPreview(); } } } @Override protected void onPause() { super.onPause(); if(camera!=null) { stopCamera(); } } /** * 相機預覽*/ private void startPreview(){ try { //相機與SurfaceView進行繫結 camera.setPreviewDisplay(sfh); //預覽的圖片旋轉 camera.setDisplayOrientation(90); camera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } /** * 停止拍照釋放資源*/ private void stopCamera(){ if(camera!=null){ camera.stopPreview(); camera.release(); camera=null; } } }
佈局xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <SurfaceView android:id="@+id/sfv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/ll_bottom"/> <RelativeLayout android:id="@+id/ll_bottom" android:layout_width="match_parent" android:layout_height="80dp" android:layout_alignParentBottom="true"> <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="70dp" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:src="@mipmap/ic_launcher"/> <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="10dp" android:text="拍照"/> </RelativeLayout> </RelativeLayout>
最後不要忘了放上許可權:
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
效果圖:
轉載https://blog.csdn.net/qq_38416326/article/details/70809754