美文网首页
android-自定义相机

android-自定义相机

作者: Oslanka | 来源:发表于2019-10-17 15:28 被阅读0次

    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 oslanka@163.com

    * 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-自定义相机

          本文链接:https://www.haomeiwen.com/subject/cscauxtx.html