1. 程式人生 > >android 自定義相機Camera

android 自定義相機Camera

專案中,有時系統的相機不能滿足我們的需求,例如:實現美圖,這樣就需要我們進行自定義相機,滿足我們的特殊需求。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