android-自定义相机

import android.Manifest;

import android.annotation.SuppressLint;

import android.app.Activity;

import android.content.Intent;

import android.content.pm.PackageManager;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Matrix;

import android.hardware.Camera;

import android.os.AsyncTask;

import android.os.Environment;

import android.support.annotation.NonNull;

import android.support.v4.content.ContextCompat;

import android.support.v7.widget.GridLayoutManager;

import android.support.v7.widget.LinearLayoutManager;

import android.support.v7.widget.RecyclerView;

import android.view.MotionEvent;

import android.view.Surface;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.RelativeLayout;

import android.widget.TextView;

import com.alibaba.android.arouter.launcher.ARouter;

import com.luck.picture.lib.config.PictureConfig;

import com.luck.picture.lib.entity.LocalMedia;

import net.qihoo.corp.iqha.base.ui.activity.IQHABaseActivity;

import net.qihoo.corp.iqha.base.utils.DensityUtils;

import net.qihoo.corp.iqha.base.utils.ToastUtil;

import net.qihoo.corp.iqha.base.utils.logger.Logger;

import net.qihoo.corp.iqha.base.widgets.MDiaglog;

import net.qihoo.corp.iqha.base.widgets.adapter.BaseQuickAdapter;

import net.qihoo.corp.module.base.R;

import net.qihoo.corp.module.base.adapter.TackPhotosAdapter;

import net.qihoo.corp.module.base.config.RoutePath;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.Serializable;

import java.util.ArrayList;

import java.util.List;

import permissions.dispatcher.NeedsPermission;

import permissions.dispatcher.RuntimePermissions;

/**

* author CaiNing

* email [email protected]

* created 2019/10/16 10:30

* version v 1.0

*/

@RuntimePermissions

public class TakeMultiPhotoActivity extends IQHABaseActivity implements SurfaceHolder.Callback {

private Camera mCamera;

    private Camera.Parameters mParams;

    private SurfaceHolder mSurfaceHolder;

    private SurfaceHolder mySurfaceHolder;

    private Camera.Size preSize;

    private SurfaceView mSurfaceView;

    private RelativeLayout layouHolder;

    private ImageView oralView;

    private int rawX;

    private int rawY;

    private ImageView ivTackPhoto;

    private TextView tvCancel;

    private ImageView changeCamera;

    private boolean catchOnePhoto;

    private int maxPhotos =9;

    private Listphotos =new ArrayList<>();

    private TextView tvOk;

    private RecyclerView recyclerView;

    private TackPhotosAdapter tackPhotosAdapter;

    private LinearLayout layoutHeader;

    @Override

    public boolean getTitleBarVisible() {

            setImmersionBar(true);

            return false;

    }

@Override

    protected int setLayoutId() {

            return R.layout.activity_tack_multi_photo;

    }

    @SuppressLint("ClickableViewAccessibility")

    @Override

    protected void initListener() {

        initView();

        int px40 =DensityUtils.dp2px(this, 40);

        layouHolder.setOnClickListener(new View.OnClickListener() {

            @Override

                public void onClick(View v) {

                        if (mCamera !=null)

                        mCamera.autoFocus(null);

                        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)oralView.getLayoutParams();

                        layoutParams.setMargins(rawX -px40, rawY -px40, 0, 0);

                        oralView.setLayoutParams(layoutParams);

                        oralView.setVisibility(View.VISIBLE);

                        oralView.postDelayed(new Runnable() {

                                @Override

                                   public void run() {

                                        if (oralView !=null)

                                            oralView.setVisibility(View.GONE);

                                        }

                        }, 500);

            }

});

        layouHolder.setOnTouchListener((v, event) -> {

            switch (event.getAction()) {

                    case MotionEvent.ACTION_DOWN:

                            rawX = (int)event.getRawX();

                            rawY = (int)event.getRawY();

                            Logger.i("info---->touch--->" +event.getX() +"--->" +event.getY() +"--->" +rawX +"--->" +rawY);

                            break;

                      case MotionEvent.ACTION_UP:

                        break;

                        case MotionEvent.ACTION_MOVE:

                        break;

            }

            return false;

        });

        ivTackPhoto.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                    takePicture();

            }

});

        tvCancel.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                setResult(RESULT_CANCELED);

                finish();

            }

});

        changeCamera.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                isBack = !isBack;

                changeCamera();

            }

});

        tvOk.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                Listresult =new ArrayList<>();

                for (int i =0; i

                    LocalMedia localMedia =new LocalMedia();

                    String path =photos.get(i);

                    localMedia.setPath(path);

                    localMedia.setCompressPath(path);

                    result.add(localMedia);

                }

Intent intent =new Intent();

                intent.putExtra(PictureConfig.EXTRA_RESULT_SELECTION,(Serializable)result);

                setResult(RESULT_OK,intent);

                finish();

            }

});

    }

public void takePicture() {//对外暴露的方法,连续拍照时调用

        if (mCamera !=null)

mCamera.takePicture(null, null, jpeg);

        showLoading();

    }

@SuppressLint("StaticFieldLeak")

public class SavePictureTask extends AsyncTask {

@SuppressLint("SimpleDateFormat")

@Override

        protected Bitmap doInBackground(byte[]...params) {

byte[]data =params[0];  //回调的数据

            Bitmap bitmap =BitmapFactory.decodeByteArray(data, 0, data.length);

            String path =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) +File.separator +"Test";

            File file =new File(path);

            if (!file.exists()) {//文件不存在就创建

                file.mkdir();

            }

String picPath =file +File.separator +System.currentTimeMillis() +".jpg";

            File pic =new File(picPath);

            try {

FileOutputStream mFos =new FileOutputStream(pic);

                //压缩

                Matrix matrix =new Matrix();

                //旋转90,拍完照的图片保存之后会自动旋转90度,在这里把图片给转回去去

                matrix.postRotate(90);

                // 创建新的图片

                Bitmap resizedBitmap =Bitmap.createBitmap(bitmap, 0, 0,

                        bitmap.getWidth(), bitmap.getHeight(), matrix, true);

                resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 85, mFos);

                mFos.close();

                if (photos.size() <=maxPhotos) {

photos.add(0,picPath);

                }

}catch (FileNotFoundException e) {

e.printStackTrace();

            }catch (IOException e) {

e.printStackTrace();

            }

return bitmap;

        }

@Override

        protected void onPostExecute(Bitmap bitmap) {

hideLoading();

            super.onPostExecute(bitmap);

//            ToastUtil.showToastShort("拍照成功了");

            layoutHeader.setVisibility(View.VISIBLE);

            tackPhotosAdapter.notifyItemInserted(0);

            recyclerView.scrollToPosition(0);

        }

}

private void changeCamera() {

initCamera();

        try {

mCamera.setPreviewDisplay(mySurfaceHolder);

        }catch (IOException ioe) {

ioe.printStackTrace();

        }

mCamera.startPreview();

        mCamera.autoFocus(null);

    }

private void initView() {

layouHolder = findViewById(R.id.layout_holder);

        oralView = findViewById(R.id.view_oral);

        ivTackPhoto = findViewById(R.id.iv_tack_photo);

        tvCancel = findViewById(R.id.tv_cancel);

        changeCamera = findViewById(R.id.change_camera);

        recyclerView = findViewById(R.id.recycler_view);

        layoutHeader = findViewById(R.id.layout_header);

        layoutHeader.setVisibility(View.GONE);

        tvOk = findViewById(R.id.tv_ok);

        tackPhotosAdapter =new TackPhotosAdapter(this, photos);

        tackPhotosAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {

@Override

            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {

String path =photos.get(position);

                ARouter.getInstance().build(RoutePath.PATH_IMAGE_ACTIVITY)

.withString("filePath",path)

.withBoolean("isLocalImage",true)

.withTransition(R.anim.slide_in_right, R.anim.slide_out_left)

.navigation(TakeMultiPhotoActivity.this);

            }

});

        tackPhotosAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {

@Override

            public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {

}

});

        recyclerView.setAdapter(tackPhotosAdapter);

        final LinearLayoutManager layoutManager =new LinearLayoutManager(this);

        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);

        recyclerView.setLayoutManager(layoutManager);

        initSurface();

    }

@Override

    public void initData() {

}

private void initSurface() {

mSurfaceView = findViewById(R.id.sf_view);

        mSurfaceHolder =mSurfaceView.getHolder();

        //mSurfaceHolder.setFixedSize(SRC_FRAME_WIDTH, SRC_FRAME_HEIGHT);

        mSurfaceHolder.addCallback(this);

        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        getCameraPosition();

    }

private boolean isBack =true;

    private void openCamera(SurfaceHolder holder) {

initCamera();

        setCameraAndOpen(holder);

    }

private void setCameraAndOpen(SurfaceHolder holder) {

mParams.setPreviewSize(preSize.width, preSize.height);

        mCamera.setParameters(mParams);

        try {

mCamera.setPreviewDisplay(holder);

        }catch (IOException ioe) {

ioe.printStackTrace();

        }

mCamera.startPreview();

        mCamera.autoFocus(null);

    }

private void initCamera() {

int mCameraId;//.CAMERA_FACING_FRONT;

//        int cameraNum = Camera.getNumberOfCameras();

//        if (cameraNum > 1)

//            mCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;

        releaseCamera(); // release Camera, if not release camera before call camera, it will be locked

        if (isBack) {

mCameraId =iBackCameraIndex;

        }else {

mCameraId =iFontCameraIndex;

        }

mCamera =Camera.open(mCameraId);

        mParams =mCamera.getParameters();

        mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

        setCameraDisplayOrientation(this, 0, mCamera);

        preSize =getCloselyPreSize(true, (int) getScreenWidth(), (int) getScreenHeight(), mParams.getSupportedPreviewSizes());

        Logger.i("----------->size" +preSize.height +"--" +preSize.width);

        float screenWidth = getScreenWidth();

        int localHeight;

        if (preSize.height

localHeight = (int) (screenWidth *preSize.width /preSize.height);

        else localHeight = (int) (screenWidth *preSize.height /preSize.width);

        ViewGroup.LayoutParams layoutParams =mSurfaceView.getLayoutParams();

        layoutParams.height =localHeight;

        mSurfaceView.setLayoutParams(layoutParams);

    }

private Camera.PictureCallback jpeg = (data, camera) -> {

if (photos.size() <=maxPhotos) {

new SavePictureTask().execute(data);  //异步保存照片

            mCamera.startPreview();

            mCamera.autoFocus(null);

        }else {

//                ToastUtil.showToastShort("最多一次拍摄"+maxPhotos+"张照片");

            MDiaglog.newInstance(TakeMultiPhotoActivity.this).setMMessage("最多一次拍摄" +maxPhotos +"张照片").setMPositiveButton("确定").show();

        }

};

    private int iFontCameraIndex =0, iBackCameraIndex =0;

    protected void getCameraPosition() {

Camera.CameraInfo cameraInfo =new Camera.CameraInfo();

        int iCameraCnt =Camera.getNumberOfCameras();

        for (int i =0; i

Camera.getCameraInfo(i, cameraInfo);

            if (cameraInfo.facing ==Camera.CameraInfo.CAMERA_FACING_FRONT) {

iFontCameraIndex = i;

            }else if (cameraInfo.facing ==Camera.CameraInfo.CAMERA_FACING_BACK) {

iBackCameraIndex = i;

            }

}

}

@Override

    protected void onPause() {

super.onPause();

    }

@Override

    protected void onResume() {

super.onResume();

    }

private void setCameraDisplayOrientation(Activity activity, int cameraId, Camera camera) {

Camera.CameraInfo info =new Camera.CameraInfo();

        Camera.getCameraInfo(cameraId, info);

        int rotation =activity.getWindowManager().getDefaultDisplay()

.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;

        }

int displayDegree;

        if (info.facing ==Camera.CameraInfo.CAMERA_FACING_FRONT) {

displayDegree = (info.orientation + degrees) %360;

            displayDegree = (360 - displayDegree) %360;  // compensate the mirror

        }else {

displayDegree = (info.orientation - degrees +360) %360;

        }

camera.setDisplayOrientation(displayDegree);

    }

private synchronized void releaseCamera() {

if (mCamera !=null) {

try {

mCamera.setPreviewCallback(null);

            }catch (Exception e) {

e.printStackTrace();

            }

try {

mCamera.stopPreview();

            }catch (Exception e) {

e.printStackTrace();

            }

try {

mCamera.release();

            }catch (Exception e) {

e.printStackTrace();

            }

mCamera =null;

        }

}

public static void open(Activity activity, int requlstCode) {

Intent mIntent =new Intent(activity, TakeMultiPhotoActivity.class);

//        mIntent.setExtrasClassLoader(Action.class.getClassLoader());

        activity.startActivityForResult(mIntent, requlstCode);

    }

@NeedsPermission(Manifest.permission.CAMERA)

void getCamera() {

if (this.mySurfaceHolder !=null) {

openCamera(mySurfaceHolder);

        }

}

@Override

    public void onRequestPermissionsResult(int requestCode, @NonNull String[]permissions, @NonNull int[]grantResults) {

super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        TakeMultiPhotoActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);

    }

public static Camera.Size getCloselyPreSize(boolean isPortrait, int surfaceWidth, int surfaceHeight, ListpreSizeList) {

//        surfaceWidth = 1080;

//        surfaceHeight = 1080;

        int reqTmpWidth;

        int reqTmpHeight;

        // 当屏幕为垂直的时候需要把宽高值进行调换,保证宽大于高

        if (isPortrait) {

reqTmpWidth =surfaceHeight;

            reqTmpHeight =surfaceWidth;

        }else {

reqTmpWidth =surfaceWidth;

            reqTmpHeight =surfaceHeight;

        }

//先查找preview中是否存在与surfaceview相同宽高的尺寸

        for (Camera.Size size :preSizeList) {

if ((size.width ==reqTmpWidth) && (size.height ==reqTmpHeight)) {

return size;

            }

}

for (Camera.Size size :preSizeList) {

if ((size.width ==1920) && (size.height ==1080)) {

return size;

            }

}

// TODO: 2019/9/25  找一个比例最接近,并且最小的

        // 得到与传入的宽高比最接近的size

        float reqRatio = ((float)reqTmpWidth) /reqTmpHeight;

        float curRatio, deltaRatio;

        float deltaRatioMin =Float.MAX_VALUE;

        Camera.Size retSize =null;

        for (Camera.Size size :preSizeList) {

curRatio = ((float)size.width) /size.height;

            deltaRatio =Math.abs(reqRatio -curRatio);

            if (deltaRatio < deltaRatioMin) {

deltaRatioMin =deltaRatio;

                retSize =size;

            }

}

return retSize;

    }

@Override

    public void surfaceCreated(SurfaceHolder holder) {

this.mySurfaceHolder =holder;

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) ==PackageManager.PERMISSION_GRANTED) {

openCamera(holder); // open camera\

        }else {

TakeMultiPhotoActivityPermissionsDispatcher.getCameraWithPermissionCheck(this);

        }

}

@Override

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

}

@Override

    public void surfaceDestroyed(SurfaceHolder holder) {

}

}

你可能感兴趣的:(android-自定义相机)