Two methods of image clipping based on android

  • 2021-12-19 06:59:08
  • OfStack

Two kinds of android picture cropping methods for your reference, the specific contents are as follows

1. After the camera takes photos, use the system's own cutting tool to intercept them


public static void cropImage(Activity activity, Uri srcUri) {
        cropImageUri = srcUri;

        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(srcUri, "image/*");
        intent.putExtra("crop", "true");

        
        // 1. When the width, height and proportion are not set, , The cropping box can be adjusted by itself ( The proportion and size can be adjusted at will )
        ////////////////////////////////////////////////////////////////
        // 2. Set only the width-height ratio of the cropping frame (aspect) Posterior , The proportion of cutting frame is fixed and cannot be adjusted , You can only resize 
        ////////////////////////////////////////////////////////////////
        // 3. Width and height of generated picture after cropping (output) The setting of is independent of the cropping box , Determine only the final generated picture size 
        ////////////////////////////////////////////////////////////////
        // 4. Width-height ratio of cutting frame (aspect) It can be scaled to the cropped generated picture (output) Different , At this time ,
        //  Will be based on the width of the cropping box , Generated according to the cutting width-height ratio 1 Pictures , This figure and box selection may be different ,
        //   Different situations may be selected by interception box 1 Part , It may also go beyond the box selection , Extend downward to make up 
        ////////////////////////////////////////////////////////////////

        // aspectX aspectY  Is the ratio of width to height of the cropping frame 
//        intent.putExtra("aspectX", 1);
//        intent.putExtra("aspectY", 1);
//        // outputX outputY  Is the width and height of the generated picture after cropping 
//        intent.putExtra("outputX", 300);
//        intent.putExtra("outputY", 300);

        // return-data For true Hour , Will return directly bitmap Data , However, there will be problems when cropping large pictures , The following is recommended false The way of time 
        // return-data For false Hour , Will not return bitmap, But you need to specify 1 A MediaStore.EXTRA_OUTPUT Save Picture uri
        intent.putExtra(MediaStore.EXTRA_OUTPUT, cropImageUri);
        intent.putExtra("return-data", false);

        activity.startActivityForResult(intent, CROP_IMAGE);

}

In this way, pictures can be freely cropped by gestures

2. Customize the camera photo interface and crop the pictures in the fixed area

A 3-party named idcardcamera is used here. Here, I pay tribute to the original author and attach the project reference address' com. github. wildma: IDCardCamera: 1.0. 0 '
There are several places that need to be modified 1. I added a rectangular box in the middle of the camera. The code fragment is as follows:


float screenMinSize = Math.min(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
        // According to screenMinSize , calculate out cameraPreview Wider of 1 Edge, aspect ratio is standard 16:9
        float maxSize = screenMinSize / 9.0f * 16.0f;
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams((int) maxSize, (int) screenMinSize);
        layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        mCameraPreview.setLayoutParams(layoutParams);
        float height = (int) (screenMinSize * 0.3);
        float density = getResources().getDisplayMetrics().density;  //  Screen density ( 0.75 / 1.0 / 1.5 ) 
        float mywdith =(int) 136*density;
        int widthPixels = getResources().getDisplayMetrics().widthPixels;
        float width = (int) (widthPixels-mywdith);//75 47
        LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams((int) width, ViewGroup.LayoutParams.MATCH_PARENT);
        LinearLayout.LayoutParams cropParams = new LinearLayout.LayoutParams((int) width, (int) height);
        mLlCameraCropContainer.setLayoutParams(containerParams);
        mIvCameraCrop.setLayoutParams(cropParams);

Modified the size of mIvCameraCrop, Add a background border to this rectangular box, I can't show the right border at first. Later, I found that the width of the father layout of the photo button is 136dp. Use the code to calculate the actual px, and then set the appropriate width of the rectangle, so that it can't be blocked. The right border can be displayed. Attach the photo logic and choose automatic clipping


/**
 *  Photographing 
 */
private void takePhoto() {
        mCameraPreview.setEnabled(false);
        mCameraPreview.takePhoto(new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(final byte[] data, Camera camera) {
//                camera.stopPreview();
                camera.startPreview();
                // Sub-threads process pictures to prevent ANR

//                setCropLayout();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                        String imagePath = path;
                        ImageUtils.save(bitmap, imagePath, Bitmap.CompressFormat.JPEG);
                        int rotation = getWindowManager().getDefaultDisplay().getRotation();
                        int angle = ImageUtils.getBitmapDegree(imagePath);
                        if (mOrientation==90){
                            bitmap = ImageUtils.rotateBitmap(CameraActivity.this.bitmap, 180);
                        }

                        /**
                         *  Calculate the clipping position 
                         */
                        float left, top, right, bottom;
                        left = ((float) mLlCameraCropContainer.getLeft() - (float) mCameraPreview.getLeft()) / (float) mCameraPreview.getWidth();
                        top = (float) mIvCameraCrop.getTop() / (float) mCameraPreview.getHeight();
                        right = (float) mLlCameraCropContainer.getRight() / (float) mCameraPreview.getWidth();
                        bottom = (float) mIvCameraCrop.getBottom() / (float) mCameraPreview.getHeight();

                        /**
                         *  Automatic cropping 
                         **/
                        mCropBitmap = 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()));

                        /**
                         *  Manual cropping 
                         **/
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                // Set the cropping area to match the scan box 1 Sample size 
                                setCropLayout();
                                mCropImageView.setLayoutParams(new LinearLayout.LayoutParams(mIvCameraCrop.getWidth(), mIvCameraCrop.getHeight()));
                                mCropImageView.setImageBitmap( mCropBitmap);
                            }
                        });
                    }
                }).start();
                safeToTakePicture = true;
            }
        });
}

Related articles: