Android comes with picture clipping (7.0, 8.0, and a millet phone)

A while ago I wrote how to get albums and photos after taking them and display and upload them. This time I made circular images. People who often read my notes will know that I am lazy.Then I'm lazy and self-defined, and the current needs are just as good as the original, the wheel of the Great God, which I'll recommend later.This note relies on: Android calls albums, cameras (compatible with 6.0, 7.0, 8.0)
The article was written, so it won't be basic. Please check that first.

First effect Ha:

##1. Layout settings
Because it is a round picture, we quote a world-famous project: CircleImageView

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_get_pic_form_photo_album"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_margin="10dp"
        android:text="Call album" />

    <Button
        android:id="@+id/btn_get_Permission"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_margin="10dp"
        android:text="Dynamic Permission Request" />

    <Button
        android:id="@+id/btn_get_pic_from_camera"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_margin="10dp"
        android:text="Call Camera" />

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/iv_test"
        android:layout_width="96dp"
        android:layout_height="96dp"
        android:layout_centerInParent="true"
        android:src="@drawable/ic_launcher_background"
        app:civ_border_color="#999999"
        app:civ_border_width="2dp" />
</RelativeLayout>

The layout hasn't changed much by changing the previous ImageView to a CircleImageView control

##2,.java file
Two methods have been added here
Method One of #######

  private void photoClip(Uri uri) {
        // Call the picture clipping that comes with the system
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        intent.setDataAndType(uri, "image/*");
        // The crop=true below is set to set the VIEW clippable display in the open Intent
        intent.putExtra("crop", "true");
        // aspectX aspectY is the ratio of width to height
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY is the width and height of the cropped picture
        intent.putExtra("outputX", 150);
        intent.putExtra("outputY", 150);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, 3);
    }

This method passes in the uri of the photo we get to activate the clipping interface of the Android system.I called this method within onActivityResult.

Method 2 of #######

  public String saveImage(String name, Bitmap bmp) {
        File appDir = new File(Environment.getExternalStorageDirectory().getPath());
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = name + ".jpg";
        File file = new File(appDir, fileName);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.flush();
            fos.close();
            return file.getAbsolutePath();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

This method passes in the bitmap to get the photo and the name of the clipped photo, and the path to save the file. Han Xiaodian saves it in the local root directory.

Complete Code

package com.example.hxd.pictest;

import android.Manifest;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import com.bumptech.glide.Glide;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.logging.Logger;

import de.hdodenhof.circleimageview.CircleImageView;
import pub.devrel.easypermissions.EasyPermissions;

public class MainActivity extends AppCompatActivity implements View.OnClickListener, EasyPermissions.PermissionCallbacks {

    private CircleImageView ivTest;

    private File cameraSavePath;//Photo Path
    private Uri uri;
    private String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};

    private String photoName = System.currentTimeMillis() + ".jpg";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnGetPicFromCamera = findViewById(R.id.btn_get_pic_from_camera);
        Button btnGetPicFromPhotoAlbum = findViewById(R.id.btn_get_pic_form_photo_album);
        Button btnGetPermission = findViewById(R.id.btn_get_Permission);
        ivTest = findViewById(R.id.iv_test);

        btnGetPicFromCamera.setOnClickListener(this);
        btnGetPicFromPhotoAlbum.setOnClickListener(this);
        btnGetPermission.setOnClickListener(this);

        cameraSavePath = new File(Environment.getExternalStorageDirectory().getPath() + "/" + photoName);

    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id) {
            case R.id.btn_get_pic_from_camera:
                goCamera();
                break;
            case R.id.btn_get_pic_form_photo_album:
                goPhotoAlbum();
                break;
            case R.id.btn_get_Permission:
                getPermission();
                break;
        }
    }

    //Get permissions
    private void getPermission() {
        if (EasyPermissions.hasPermissions(this, permissions)) {
            //Permissions already open
            Toast.makeText(this, "Permissions have been applied for", Toast.LENGTH_SHORT).show();
        } else {
            //No open related permissions, application permissions
            EasyPermissions.requestPermissions(this, "Require access to your albums, photos", 1, permissions);
        }

    }


    private void photoClip(Uri uri) {
        // Call the picture clipping that comes with the system
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        // The crop=true below is set to set the VIEW clippable display in the open Intent
        intent.putExtra("crop", "true");
        // aspectX aspectY is the ratio of width to height
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY is the width and height of the cropped picture
        intent.putExtra("outputX", 150);
        intent.putExtra("outputY", 150);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, 3);


    }


    //Activate Album Operation
    private void goPhotoAlbum() {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_PICK);
        intent.setType("image/*");
        startActivityForResult(intent, 2);
    }

    //Activate Camera Operation
    private void goCamera() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            uri = FileProvider.getUriForFile(MainActivity.this, "com.example.hxd.pictest.fileprovider", cameraSavePath);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        } else {
            uri = Uri.fromFile(cameraSavePath);
        }
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        MainActivity.this.startActivityForResult(intent, 1);
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //The framework requires this
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }


    //Successfully opened permissions
    @Override
    public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {

        Toast.makeText(this, "Related Permissions Successfully Acquired", Toast.LENGTH_SHORT).show();
    }

    //User does not agree to permissions
    @Override
    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
        Toast.makeText(this, "Please agree to the permissions, otherwise the function will not be available", Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        String photoPath;
        if (requestCode == 1 && resultCode == RESULT_OK) {

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                photoPath = String.valueOf(cameraSavePath);
                photoClip(Uri.fromFile(cameraSavePath));
            } else {
                photoPath = uri.getEncodedPath();
                photoClip(uri);
            }
            Log.d("Photo Return to Picture Path:", photoPath);
            Glide.with(MainActivity.this).load(photoPath).into(ivTest);
        } else if (requestCode == 2 && resultCode == RESULT_OK) {
            photoPath = getPhotoFromPhotoAlbum.getRealPathFromUri(this, data.getData());
            Log.d("Album Return Picture Path:", photoPath);
            photoClip(data.getData());
            Glide.with(MainActivity.this).load(photoPath).into(ivTest);
        } else if (requestCode == 3 && resultCode == RESULT_OK) {
            Bundle bundle = data.getExtras();

            if (bundle != null) {
                //Here you get a clipped Bitmap object that you can use to upload
                Bitmap image = bundle.getParcelable("data");
                //Set on ImageView
                ivTest.setImageBitmap(image);
                //You can also save, compress, and upload
                String path = saveImage("Head portrait", image);
                Log.d("clipping path:", path);
            }


        }

        super.onActivityResult(requestCode, resultCode, data);
    }

    public String saveImage(String name, Bitmap bmp) {
        File appDir = new File(Environment.getExternalStorageDirectory().getPath());
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = name + ".jpg";
        File file = new File(appDir, fileName);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.flush();
            fos.close();
            return file.getAbsolutePath();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

When the code was written like this, I thought I could finish it, but when I took out my millet 4 and millet 8se tests, I was confused and the following results appeared:

Describe:
1. After the album has selected the photo, as long as the photo is clipped, an error will occur during the save and the save will fail.
2. Clipping after taking a photo has no effect.

#3. Solving bug s
###1, add the following code to the photoClip() method, and leave the rest unchanged

uritempFile = Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath() + "/" + System.currentTimeMillis() + ".jpg");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true); 

The uritempFile here is a Uri.

###2, add the following code to the clipped return successful return method:

  Picasso.with(EditMyInfoActivity.this).load(uritempFile).into(ivHead);
            File file = null;
            try {
                file = new File(new URI(uritempFile.toString()));
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
            //Photo Path
            String path = Objects.requireNonNull(file).getPath();

Then you can run perfectly.
##3. Recommend a custom clipped blog
Android high mimic WeChat avatar intercepts to create different custom controls - - Author: the well-known Zhang Hongyang

##4. Recommend several clipping frames
1,uCrop - Mint, beer and beer in use

2,android-crop - NetEase News, Mango TV in use

3,PhotoCrop - Fast-hand use

4,CropBitmap ->From a group friend of Niu x

Tags: Android Java FileProvider xml

Posted on Fri, 10 May 2019 13:08:50 -0400 by ifubad