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 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) {

}

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,332评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,930评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,204评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,348评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,356评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,447评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,862评论 3 394
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,516评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,710评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,518评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,582评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,295评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,848评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,881评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,121评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,737评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,280评论 2 341

推荐阅读更多精彩内容