close

想要直接預覽相機的畫面可以利用SurfaceView的方法呈現並存取下來


Step 1:

在Gradle裡面加入

compile 'com.google.android.gms:play-services-vision:9.4.0+'

後面的版本編號可能要看你現在相對應的

 

Step 2:

在AndroidManifest加入

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

 

Step 3:

拉layout

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <SurfaceView
        android:id="@+id/surfaceview"
        android:layout_width="368dp"
        android:layout_height="0dp"
        android:layout_centerHorizontal="true"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="8dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        android:layout_marginBottom="0dp"
        app:layout_constraintBottom_toTopOf="@+id/take"
        app:layout_constraintVertical_bias="0.479" />

    <Button
        android:id="@+id/take"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Take Photo"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent" />

</android.support.constraint.ConstraintLayout>

 

Step 4:

完整程式碼

public class CameraActivity extends Activity {
    private SurfaceView mian_sfv_id;
    private Camera camera;
    private Button take;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);

        mian_sfv_id = (SurfaceView) findViewById(R.id.surfaceview);
        take = (Button) findViewById(R.id.take);

        //SurfaceView設置監聽器
        mian_sfv_id.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                camera=Camera.open();
                Camera.Parameters parameters = camera.getParameters();
                //畫面旋轉
                int rotation = getDisplayOrientation();
                camera.setDisplayOrientation(rotation);
                //相機會自動對焦
                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                camera.setParameters(parameters);
                //將畫面顯示到SurfaceView
                try {
                    camera.setPreviewDisplay(mian_sfv_id.getHolder());
                    camera.startPreview();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                if (camera!=null){
                    camera.stopPreview();
                    camera.release();
                }
            }
        });

        take.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                camera.autoFocus(afcb);
            }
        });
    }

    //讓呈現的畫面跟使用者是同一個方向
    public int getDisplayOrientation() {
        Display display = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        int rotation = display.getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }
        android.hardware.Camera.CameraInfo camInfo = new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, camInfo);
        int result = (camInfo.orientation - degrees + 360) % 360;
        return result;
    }

    PictureCallback jpeg =new PictureCallback(){
        public void onPictureTaken(byte[] data, Camera camera) {
            Bitmap bmp=BitmapFactory.decodeByteArray(data, 0, data.length);
            //得到bitmap後取得照片的Uri
            Uri uri = getImageUri(bmp);
            //利用Uri去取得照片的路徑
            String path = getRealPathFromURI(uri);
            //將照片存入到手機裡
            saveBitmapFile(bmp,new File(path));

            camera.startPreview();
        }
    };

    Camera.AutoFocusCallback afcb= new Camera.AutoFocusCallback(){
        public void onAutoFocus(boolean success, Camera camera) {
            if(success){
                //對焦成功才拍照
                camera.takePicture(null, null, jpeg);
            }
        }
    };

    public Uri getImageUri(Bitmap inImage) {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
        String path = MediaStore.Images.Media.insertImage(getContentResolver(), inImage, "Title", null);
        return Uri.parse(path);
    }
    public String getRealPathFromURI(Uri uri) {
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);
        cursor.moveToFirst();
        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
        return cursor.getString(idx);
    }
    public static void saveBitmapFile(Bitmap bitmap, File file) {
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            bos.flush();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
arrow
arrow

    小小工程師 發表在 痞客邦 留言(0) 人氣()