Android中身份证正反面、营业执照横竖版的拍摄和裁剪

借鉴GitHub:https://github.com/smartown/CertificateCamera

做之前可以在GitHub上看看效果是否符合自己的要求。因为之前导入他人Demo因版本不同总是出现各种问题,所以我这里就是把他其中的代码给粘贴出来,不知是否违规,还望大家提醒。其中的图片资源、values下、drawable下的资源我就不写了。

一、先看拍照时页面布局,有两种,其一在layout中,其二在layout-land中,也就是说你需要在res下创建一个名为layout-land的文件夹。

1. layout

<?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"
    android:background="#000">

    <com.example.zyt.mynewimageview.img.CameraPreview
        android:id="@+id/camera_surface"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:background="@color/preview_mock"
                android:gravity="center"
                android:text="@string/touch_to_focus"
                android:textColor="#afff"
                android:textSize="16dp" />

            <LinearLayout
                android:id="@+id/camera_crop_container"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:orientation="horizontal">

                <View
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:background="@color/preview_mock" />

                <ImageView
                    android:id="@+id/camera_crop"
                    android:layout_width="0dp"
                    android:layout_height="0dp"
                    android:scaleType="fitXY" />

                <View
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:background="@color/preview_mock" />

            </LinearLayout>

        </LinearLayout>

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="136dp"
            android:background="@color/preview_mock">

            <LinearLayout
                android:id="@+id/camera_option"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:orientation="horizontal">

                <ImageView
                    android:id="@+id/camera_close"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:src="@mipmap/camera_close" />

                <ImageView
                    android:id="@+id/camera_take"
                    android:layout_width="72dp"
                    android:layout_height="72dp"
                    android:layout_margin="32dp"
                    android:src="@mipmap/camera_take" />

                <ImageView
                    android:id="@+id/camera_flash"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:src="@mipmap/camera_flash_off" />

            </LinearLayout>

            <LinearLayout
                android:id="@+id/camera_result"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:orientation="horizontal"
                android:visibility="gone">

                <ImageView
                    android:id="@+id/camera_result_cancel"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:src="@mipmap/camera_result_cancel" />

                <ImageView
                    android:id="@+id/camera_result_ok"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:layout_marginLeft="80dp"
                    android:src="@mipmap/camera_result_ok" />

            </LinearLayout>

        </FrameLayout>

    </LinearLayout>
</RelativeLayout>

 2. layout-land

<?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"
    android:background="#000">

    <com.example.zyt.mynewimageview.img.CameraPreview
        android:id="@+id/camera_surface"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">

            <View
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="@color/preview_mock" />

            <LinearLayout
                android:id="@+id/camera_crop_container"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:orientation="vertical">

                <View
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:layout_weight="1"
                    android:background="@color/preview_mock" />

                <ImageView
                    android:id="@+id/camera_crop"
                    android:layout_width="0dp"
                    android:layout_height="0dp"
                    android:scaleType="fitXY" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:layout_weight="1"
                    android:background="@color/preview_mock"
                    android:gravity="center"
                    android:text="@string/touch_to_focus"
                    android:textColor="#afff"
                    android:textSize="16dp" />

            </LinearLayout>

        </LinearLayout>

        <FrameLayout
            android:layout_width="136dp"
            android:layout_height="match_parent"
            android:background="@color/preview_mock">

            <LinearLayout
                android:id="@+id/camera_option"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:orientation="vertical">

                <ImageView
                    android:id="@+id/camera_flash"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:src="@mipmap/camera_flash_off" />

                <ImageView
                    android:id="@+id/camera_take"
                    android:layout_width="72dp"
                    android:layout_height="72dp"
                    android:layout_margin="32dp"
                    android:src="@mipmap/camera_take" />

                <ImageView
                    android:id="@+id/camera_close"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:src="@mipmap/camera_close" />

            </LinearLayout>

            <LinearLayout
                android:id="@+id/camera_result"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:orientation="vertical"
                android:visibility="gone">

                <ImageView
                    android:id="@+id/camera_result_ok"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:src="@mipmap/camera_result_ok" />

                <ImageView
                    android:id="@+id/camera_result_cancel"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:layout_marginTop="80dp"
                    android:src="@mipmap/camera_result_cancel" />

            </LinearLayout>

        </FrameLayout>

    </LinearLayout>
</RelativeLayout>

二、实现布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/main_image"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:scaleType="fitCenter" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="8dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:layout_width="0dp"
                android:layout_height="48dp"
                android:layout_margin="8dp"
                android:layout_weight="1"
                android:background="@drawable/shape_button"
                android:gravity="center"
                android:onClick="frontIdCard"
                android:text="身份证正面"
                android:textColor="#555"
                android:textSize="16dp" />

            <TextView
                android:layout_width="0dp"
                android:layout_height="48dp"
                android:layout_margin="8dp"
                android:layout_weight="1"
                android:background="@drawable/shape_button"
                android:gravity="center"
                android:onClick="backIdCard"
                android:text="身份证反面"
                android:textColor="#555"
                android:textSize="16dp" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:layout_width="0dp"
                android:layout_height="48dp"
                android:layout_margin="8dp"
                android:layout_weight="1"
                android:background="@drawable/shape_button"
                android:gravity="center"
                android:onClick="businessLicensePortrait"
                android:text="营业执照竖版"
                android:textColor="#555"
                android:textSize="16dp" />

            <TextView
                android:layout_width="0dp"
                android:layout_height="48dp"
                android:layout_margin="8dp"
                android:layout_weight="1"
                android:background="@drawable/shape_button"
                android:gravity="center"
                android:onClick="businessLicenseLandscape"
                android:text="营业执照横版"
                android:textColor="#555"
                android:textSize="16dp" />

        </LinearLayout>

    </LinearLayout>

</LinearLayout>

三、工具类CameraUtils

public class CameraUtils {
    /**
     * Check if this device has a camera
     * 检查这个设备是否有摄像头
     */
    public static boolean hasCamera(Context context) {
        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
            // this device has a camera
            return true;
        } else {
            // no camera on this device
            return false;
        }
    }

    /**
     * A safe way to get an instance of the Camera object.
     * 获取摄像机对象实例的安全方法。
     */
    public static Camera openCamera() {
        Camera c = null;
        try {
            c = Camera.open(); // attempt to get a Camera instance
        } catch (Exception e) {
            // Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }
}

四、自定义控件CameraPreview

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

    private static String TAG = CameraPreview.class.getName();

    private Camera camera;

    public CameraPreview(Context context) {
        super(context);
        init();
    }

    public CameraPreview(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CameraPreview(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public CameraPreview(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    private void init() {
        SurfaceHolder surfaceHolder = getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setKeepScreenOn(true);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        camera = CameraUtils.openCamera();
        if (camera != null) {
            try {
                camera.setPreviewDisplay(holder);
                Camera.Parameters parameters = camera.getParameters();
                if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                    //竖屏拍照时,需要设置旋转90度,否者看到的相机预览方向和界面方向不相同
                    camera.setDisplayOrientation(90);
                    parameters.setRotation(90);
                } else {
                    camera.setDisplayOrientation(0);
                    parameters.setRotation(0);
                }
                Camera.Size bestSize = getBestSize(parameters.getSupportedPreviewSizes());
                if (bestSize != null) {
                    parameters.setPreviewSize(bestSize.width, bestSize.height);
                    parameters.setPictureSize(bestSize.width, bestSize.height);
                } else {
                    parameters.setPreviewSize(1920, 1080);
                    parameters.setPictureSize(1920, 1080);
                }
                camera.setParameters(parameters);
                camera.startPreview();
                focus();
            } catch (Exception e) {
                Log.d(TAG, "Error setting camera preview: " + e.getMessage());
                try {
                    Camera.Parameters parameters = camera.getParameters();
                    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                        //竖屏拍照时,需要设置旋转90度,否者看到的相机预览方向和界面方向不相同
                        camera.setDisplayOrientation(90);
                        parameters.setRotation(90);
                    } else {
                        camera.setDisplayOrientation(0);
                        parameters.setRotation(0);
                    }
                    camera.setParameters(parameters);
                    camera.startPreview();
                    focus();
                } catch (Exception e1) {
                    e.printStackTrace();
                    camera = null;
                }
            }
        }
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        //因为设置了固定屏幕方向,所以在实际使用中不会触发这个方法
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        //回收释放资源
        release();
    }

    /**
     * Android相机的预览尺寸都是4:3或者16:9,这里遍历所有支持的预览尺寸,得到16:9的最大尺寸,保证成像清晰度
     *
     * @param sizes
     * @return 最佳尺寸
     */
    private Camera.Size getBestSize(List<Camera.Size> sizes) {
        Camera.Size bestSize = null;
        for (Camera.Size size : sizes) {
            if ((float) size.width / (float) size.height == 16.0f / 9.0f) {
                if (bestSize == null) {
                    bestSize = size;
                } else {
                    if (size.width > bestSize.width) {
                        bestSize = size;
                    }
                }
            }
        }
        return bestSize;
    }

    /**
     * 释放资源
     */
    private void release() {
        if (camera != null) {
            camera.stopPreview();
            camera.release();
            camera = null;
        }
    }

    /**
     * 对焦,在CameraActivity中触摸对焦
     */
    public void focus() {
        if (camera != null) {
            camera.autoFocus(null);
        }
    }

    /**
     * 开关闪光灯
     *
     * @return 闪光灯是否开启
     */
    public boolean switchFlashLight() {
        if (camera != null) {
            Camera.Parameters parameters = camera.getParameters();
            if (parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_OFF)) {
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                camera.setParameters(parameters);
                return true;
            } else {
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                camera.setParameters(parameters);
                return false;
            }
        }
        return false;
    }

    /**
     * 拍摄照片
     *
     * @param pictureCallback 在pictureCallback处理拍照回调
     */
    public void takePhoto(Camera.PictureCallback pictureCallback) {
        if (camera != null) {
            camera.takePicture(null, null, pictureCallback);
        }
    }

    public void startPreview() {
        if (camera != null) {
            camera.startPreview();
        }
    }

}

五、相机CameraActivity

public class CameraActivity extends Activity implements View.OnClickListener {

    /**
     * 拍摄类型-身份证正面
     */
    public final static int TYPE_IDCARD_FRONT = 1;
    /**
     * 拍摄类型-身份证反面
     */
    public final static int TYPE_IDCARD_BACK = 2;
    /**
     * 拍摄类型-竖版营业执照
     */
    public final static int TYPE_COMPANY_PORTRAIT = 3;
    /**
     * 拍摄类型-横版营业执照
     */
    public final static int TYPE_COMPANY_LANDSCAPE = 4;

    public final static int REQUEST_CODE = 0X13;
    public final static int RESULT_CODE = 0X14;

    /**
     * @param type {@link #TYPE_IDCARD_FRONT}
     *             {@link #TYPE_IDCARD_BACK}
     *             {@link #TYPE_COMPANY_PORTRAIT}
     *             {@link #TYPE_COMPANY_LANDSCAPE}
     */
    public static void openCertificateCamera(Activity activity, int type) {
        Intent intent = new Intent(activity, CameraActivity.class);
        intent.putExtra("type", type);
        activity.startActivityForResult(intent, REQUEST_CODE);
    }

    /**
     * @return 结果文件路径
     */
    public static String getResult(Intent data) {
        if (data != null) {
            return data.getStringExtra("result");
        }
        return "";
    }

    private CameraPreview cameraPreview;
    private View containerView;
    private ImageView cropView;
    private ImageView flashImageView;
    private View optionView;
    private View resultView;

    private int type;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        type = getIntent().getIntExtra("type", 0);
        if (type == TYPE_COMPANY_PORTRAIT) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        }
        setContentView(R.layout.activity_camera);
        cameraPreview = (CameraPreview) findViewById(R.id.camera_surface);
        //获取屏幕最小边,设置为cameraPreview较窄的一边
        float screenMinSize = Math.min(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
        //根据screenMinSize,计算出cameraPreview的较宽的一边,长宽比为标准的16:9
        float maxSize = screenMinSize / 9.0f * 16.0f;
        RelativeLayout.LayoutParams layoutParams;
        if (type == TYPE_COMPANY_PORTRAIT) {
            layoutParams = new RelativeLayout.LayoutParams((int) screenMinSize, (int) maxSize);
        } else {
            layoutParams = new RelativeLayout.LayoutParams((int) maxSize, (int) screenMinSize);
        }
        layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        cameraPreview.setLayoutParams(layoutParams);

        containerView = findViewById(R.id.camera_crop_container);
        cropView = (ImageView) findViewById(R.id.camera_crop);
        if (type == TYPE_COMPANY_PORTRAIT) {
            float width = (int) (screenMinSize * 0.8);
            float height = (int) (width * 43.0f / 30.0f);
            LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) height);
            LinearLayout.LayoutParams cropParams = new LinearLayout.LayoutParams((int) width, (int) height);
            containerView.setLayoutParams(containerParams);
            cropView.setLayoutParams(cropParams);
        } else if (type == TYPE_COMPANY_LANDSCAPE) {
            float height = (int) (screenMinSize * 0.8);
            float width = (int) (height * 43.0f / 30.0f);
            LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams((int) width, ViewGroup.LayoutParams.MATCH_PARENT);
            LinearLayout.LayoutParams cropParams = new LinearLayout.LayoutParams((int) width, (int) height);
            containerView.setLayoutParams(containerParams);
            cropView.setLayoutParams(cropParams);
        } else {
            float height = (int) (screenMinSize * 0.75);
            float width = (int) (height * 75.0f / 47.0f);
            LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams((int) width, ViewGroup.LayoutParams.MATCH_PARENT);
            LinearLayout.LayoutParams cropParams = new LinearLayout.LayoutParams((int) width, (int) height);
            containerView.setLayoutParams(containerParams);
            cropView.setLayoutParams(cropParams);
        }
        switch (type) {
            case TYPE_IDCARD_FRONT:
                cropView.setImageResource(R.mipmap.camera_idcard_front);
                break;
            case TYPE_IDCARD_BACK:
                cropView.setImageResource(R.mipmap.camera_idcard_back);
                break;
            case TYPE_COMPANY_PORTRAIT:
                cropView.setImageResource(R.mipmap.camera_company);
                break;
            case TYPE_COMPANY_LANDSCAPE:
                cropView.setImageResource(R.mipmap.camera_company_landscape);
                break;
        }

        flashImageView = (ImageView) findViewById(R.id.camera_flash);
        optionView = findViewById(R.id.camera_option);
        resultView = findViewById(R.id.camera_result);
        cameraPreview.setOnClickListener(this);
        findViewById(R.id.camera_close).setOnClickListener(this);
        findViewById(R.id.camera_take).setOnClickListener(this);
        flashImageView.setOnClickListener(this);
        findViewById(R.id.camera_result_ok).setOnClickListener(this);
        findViewById(R.id.camera_result_cancel).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.camera_surface) {
            cameraPreview.focus();
        } else if (id == R.id.camera_close) {
            finish();
        } else if (id == R.id.camera_take) {
            takePhoto();
        } else if (id == R.id.camera_flash) {
            boolean isFlashOn = cameraPreview.switchFlashLight();
            flashImageView.setImageResource(isFlashOn ? R.mipmap.camera_flash_on : R.mipmap.camera_flash_off);
        } else if (id == R.id.camera_result_ok) {
            goBack();
        } else if (id == R.id.camera_result_cancel) {
            optionView.setVisibility(View.VISIBLE);
            cameraPreview.setEnabled(true);
            resultView.setVisibility(View.GONE);
            cameraPreview.startPreview();
        }
    }

    private void takePhoto() {
        optionView.setVisibility(View.GONE);
        cameraPreview.setEnabled(false);
        cameraPreview.takePhoto(new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(final byte[] data, Camera camera) {
                camera.stopPreview();
                //子线程处理图片,防止ANR
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            File originalFile = getOriginalFile();
                            FileOutputStream originalFileOutputStream = new FileOutputStream(originalFile);
                            originalFileOutputStream.write(data);
                            originalFileOutputStream.close();

                            Bitmap bitmap = BitmapFactory.decodeFile(originalFile.getPath());

                            //计算裁剪位置
                            float left, top, right, bottom;
                            if (type == TYPE_COMPANY_PORTRAIT) {
                                left = (float) cropView.getLeft() / (float) cameraPreview.getWidth();
                                top = ((float) containerView.getTop() - (float) cameraPreview.getTop()) / (float) cameraPreview.getHeight();
                                right = (float) cropView.getRight() / (float) cameraPreview.getWidth();
                                bottom = (float) containerView.getBottom() / (float) cameraPreview.getHeight();
                            } else {
                                left = ((float) containerView.getLeft() - (float) cameraPreview.getLeft()) / (float) cameraPreview.getWidth();
                                top = (float) cropView.getTop() / (float) cameraPreview.getHeight();
                                right = (float) containerView.getRight() / (float) cameraPreview.getWidth();
                                bottom = (float) cropView.getBottom() / (float) cameraPreview.getHeight();
                            }
                            //裁剪及保存到文件
                            Bitmap cropBitmap = Bitmap.createBitmap(bitmap,
                                    (int) (left * (float) bitmap.getWidth()),
                                    (int) (top * (float) bitmap.getHeight()),
                                    (int) ((right - left) * (float) bitmap.getWidth()),
                                    (int) ((bottom - top) * (float) bitmap.getHeight()));

                            final File cropFile = getCropFile();
                            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(cropFile));
                            cropBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
                            bos.flush();
                            bos.close();
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    resultView.setVisibility(View.VISIBLE);
                                }
                            });
                            return;
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                optionView.setVisibility(View.VISIBLE);
                                cameraPreview.setEnabled(true);
                            }
                        });
                    }
                }).start();

            }
        });
    }

    /**
     * @return 拍摄图片原始文件
     */
    private File getOriginalFile() {
        switch (type) {
            case TYPE_IDCARD_FRONT:
                return new File(getExternalCacheDir(), "idCardFront.png");
            case TYPE_IDCARD_BACK:
                return new File(getExternalCacheDir(), "idCardBack.png");
            case TYPE_COMPANY_PORTRAIT:
            case TYPE_COMPANY_LANDSCAPE:
                return new File(getExternalCacheDir(), "companyInfo.jpg");
        }
        return new File(getExternalCacheDir(), "picture.jpg");
    }

    /**
     * @return 拍摄图片裁剪文件
     */
    private File getCropFile() {
        switch (type) {
            case TYPE_IDCARD_FRONT:
                return new File(getExternalCacheDir(), "idCardFrontCrop.jpg");
            case TYPE_IDCARD_BACK:
                return new File(getExternalCacheDir(), "idCardBackCrop.jpg");
            case TYPE_COMPANY_PORTRAIT:
            case TYPE_COMPANY_LANDSCAPE:
                return new File(getExternalCacheDir(), "companyInfoCrop.jpg");
        }
        return new File(getExternalCacheDir(), "pictureCrop.jpg");
    }

    /**
     * 点击对勾,使用拍照结果,返回对应图片路径
     */
    private void goBack() {
        Intent intent = new Intent();
        intent.putExtra("result", getCropFile().getPath());
        setResult(RESULT_CODE, intent);
        finish();
    }

}

六、实现MainActivity

public class MainActivity extends AppCompatActivity {

    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.main_image);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CameraActivity.REQUEST_CODE && resultCode == CameraActivity.RESULT_CODE) {
            //获取文件路径,显示图片
            final String path = CameraActivity.getResult(data);
            if (!TextUtils.isEmpty(path)) {
                imageView.setImageBitmap(BitmapFactory.decodeFile(path));
            }
        }
    }

    /**
     * 拍摄证件照片
     *
     * @param type 拍摄证件类型
     */
    private void takePhoto(int type) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 0x12);
            return;
        }
        CameraActivity.openCertificateCamera(this, type);
    }

    /**
     * 身份证正面
     */
    public void frontIdCard(View view) {
        takePhoto(CameraActivity.TYPE_IDCARD_FRONT);
    }

    /**
     * 身份证反面
     */
    public void backIdCard(View view) {
        takePhoto(CameraActivity.TYPE_IDCARD_BACK);
    }

    /**
     * 营业执照竖版
     */
    public void businessLicensePortrait(View view) {
        takePhoto(CameraActivity.TYPE_COMPANY_PORTRAIT);
    }

    /**
     * 营业执照横版
     */
    public void businessLicenseLandscape(View view) {
        takePhoto(CameraActivity.TYPE_COMPANY_LANDSCAPE);
    }

}

七、清单文件AndroidManifest

1. 注册CameraActivity

    <activity
            android:name=".img.CameraActivity"
            android:screenOrientation="landscape"
            android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen" />

2. 权限

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

    <uses-feature
        android:name="android.hardware.camera"
        android:required="true" />
    <uses-feature
        android:name="android.hardware.camera.autofocus"
        android:required="true" />

 

以下是一个简单的示例代码,演示如何自动裁剪身份证正反面图片: ```csharp using System; using System.Drawing; public static void AutoCropIDCard(string imagePath, string croppedImagePath) { // 加载原始图片 Image originalImage = Image.FromFile(imagePath); // 计算身份证的宽度高度 int idCardWidth = 850; int idCardHeight = 540; // 计算正面反面图片的左上角坐标宽度高度 int frontX = 30; int frontY = 74; int frontWidth = 388; int frontHeight = 276; int backX = 435; int backY = 74; int backWidth = 388; int backHeight = 276; // 创建一个新的身份证大小的图片 Image croppedImage = new Bitmap(idCardWidth, idCardHeight); // 创建一个 Graphics 对象,用于在新图片上绘制原始图片的一部分 Graphics graphics = Graphics.FromImage(croppedImage); // 定义一个矩形,表示要截取的正面图片区域 Rectangle frontSourceRectangle = new Rectangle(frontX, frontY, frontWidth, frontHeight); // 定义一个矩形,表示要绘制的正面图片目标区域 Rectangle frontDestinationRectangle = new Rectangle(0, 0, frontWidth, frontHeight); // 绘制原始图片的正面部分到新图片上 graphics.DrawImage(originalImage, frontDestinationRectangle, frontSourceRectangle, GraphicsUnit.Pixel); // 定义一个矩形,表示要截取的反面图片区域 Rectangle backSourceRectangle = new Rectangle(backX, backY, backWidth, backHeight); // 定义一个矩形,表示要绘制的反面图片目标区域 Rectangle backDestinationRectangle = new Rectangle(frontWidth, 0, backWidth, backHeight); // 绘制原始图片的反面部分到新图片上 graphics.DrawImage(originalImage, backDestinationRectangle, backSourceRectangle, GraphicsUnit.Pixel); // 保存新图片 croppedImage.Save(croppedImagePath, ImageFormat.Jpeg); // 释放资源 graphics.Dispose(); croppedImage.Dispose(); originalImage.Dispose(); } ``` 在这个示例中,`imagePath` 参数是原始图片的路径,`croppedImagePath` 参数是要保存的新图片的路径。 这个方法会读取原始图片,根据身份证正反面图片的位置大小,自动裁剪正反面图片,并将它们合并成一个新图片。最后,它会保存新图片到指定的路径。 您可以调用 `AutoCropIDCard` 方法来自动裁剪身份证图片。例如: ```csharp string imagePath = "path/to/image.jpg"; string croppedImagePath = "path/to/cropped/image.jpg"; AutoCropIDCard(imagePath, croppedImagePath); ``` 这个方法会读取原始图片,自动裁剪身份证正反面图片,并将它们合并成一个新图片,并将结果保存到新图片中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值