androidandroid-intentimage-quality

Android gallery intent: How can i get and set original cropped image with full size and good quality instead of thumbnail?


Below is my edit profile activity where i give user an option to set the profile pic from gallery. When user clicks to edit profile pic, it opens up gallery, crop the selected image, cropped image will be saved at pre-defined location as well as temp location, cropped image will be set as profile pic. However, it always gets thumbnail or low quality image. The quality of image is same as of just like how we pass the image into the intent through uri and then get that image uri with getData and then setting up the image with setImageUri, because in such way it will give thumbnail and not the original image. That's why i tried first to save that cropped image and then get it from there. Even to avoid OOM (Out Of Memory) error, i tried to adjust the image quality and compression using inSampleSize, bitmap factory option and all... but at the end, what i get is always the same thumbnail type image quality!

What i want is as said in title, original cropped image to set for userImageView and not kind of thumbnail or low resolution image!

Also consider that i am new in android development as well as in programming, coding and all!

Any kind of help will be appreciated!

public class EditUserProfile extends AppCompatActivity {

    private CoordinatorLayout coordinatorLayout;

    public static final String Uimage = "Uimagepath";
    public static final String Name = "nameKey";
    public static final String UContact = "UContact";
    public static final String Uemail = "Uemail";

    private TextInputLayout inputLayoutName, inputLayoutEmail, inputLayoutContact;
    private EditText usernameTextView, userEmailTextView, userContactTextView;
    private ImageView userImageView;

    SharedPreferences sharedpreferences;
    private int PICK_IMAGE_REQUEST = 1;

    String stringUri;
    Uri outputFileUri;
    Uri uriString;
    Uri picUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_user_profile);
        Toolbar userProfileToolbar = (Toolbar) findViewById(R.id.my_toolbar);
        setSupportActionBar(userProfileToolbar);

        inputLayoutName = (TextInputLayout) findViewById(R.id.input_layout_username);
        inputLayoutEmail = (TextInputLayout) findViewById(R.id.input_layout_useremail);
        inputLayoutContact = (TextInputLayout) findViewById(R.id.input_layout_usercontact);

        userImageView = (ImageView) findViewById(R.id.userImage);
        usernameTextView = (EditText) findViewById(R.id.username);
        userContactTextView = (EditText) findViewById(R.id.usercontact);
        userEmailTextView = (EditText) findViewById(R.id.useremail);

        Button btnSave = (Button) findViewById(R.id.action_save);


        sharedpreferences = getSharedPreferences(Uimage, Context.MODE_PRIVATE);
        sharedpreferences = getSharedPreferences(Name, Context.MODE_PRIVATE);
        sharedpreferences = getSharedPreferences(UContact, Context.MODE_PRIVATE);
        sharedpreferences = getSharedPreferences(Uemail, Context.MODE_PRIVATE);

        if (sharedpreferences.contains(Uimage)) {
            String imagepath = sharedpreferences.getString(Uimage, "");
            uriString = Uri.parse(imagepath);
            userImageView.setImageURI(uriString);
        }

        if (sharedpreferences.contains(Name)) {
            usernameTextView.setText(sharedpreferences.getString(Name, ""));
        }
        if (sharedpreferences.contains(UContact)) {
            userContactTextView.setText(sharedpreferences.getString(UContact, ""));
        }
        if (sharedpreferences.contains(Uemail)) {
            userEmailTextView.setText(sharedpreferences.getString(Uemail, ""));
        }

        usernameTextView.addTextChangedListener(new MyTextWatcher(usernameTextView));
        userEmailTextView.addTextChangedListener(new MyTextWatcher(userEmailTextView));
        userContactTextView.addTextChangedListener(new MyTextWatcher(userContactTextView));

        coordinatorLayout = (CoordinatorLayout) findViewById(R.id
                .coordinatorLayout);

        final ImageButton button = (ImageButton) findViewById(R.id.editImage);
        assert button != null;
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Perform action on click

                Intent intent = new Intent();
                // start the activity - we handle returning in onActivityResult
                intent.setAction(Intent.ACTION_GET_CONTENT);
                // Show only images, no videos or anything else
                intent.setDataAndType(picUri, "image/*");
                // set crop properties
                intent.putExtra("crop", "true");
                // indicate aspect of desired crop
                intent.putExtra("aspectX", 1);
                intent.putExtra("aspectY", 1);
                // indicate output X and Y
                intent.putExtra("outputX", 360);
                intent.putExtra("outputY", 360);
                // retrieve data on return
                intent.putExtra("return-data", false);
                File file = new File(Environment.getExternalStorageDirectory() + File.separator + "image.jpg");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
                // Always show the chooser (if there are multiple options available)
                startActivityForResult(Intent.createChooser(intent, "Select Pic from"), PICK_IMAGE_REQUEST);
            }
        });
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == PICK_IMAGE_REQUEST) {

            //Get our saved file into a bitmap object:
            File file = new File(Environment.getExternalStorageDirectory() + File.separator + "image.jpg");
            Bitmap Croppedbitmap = decodeSampledBitmapFromFile(file.getAbsolutePath(), 1000, 700);

            userImageView.setImageBitmap(Croppedbitmap);

            String root = Environment.getExternalStorageDirectory().toString();
            File myDir = new File(root + "/MyApp");

            if (!myDir.exists())
                myDir.mkdirs();

            Random generator = new Random();
            int n = 100;
            n = generator.nextInt(n);
            String fname = "Image_" + n + 1 + ".png";
            File file2 = new File(myDir, fname);
            outputFileUri = Uri.fromFile(file2);
            stringUri = outputFileUri.toString();

            SharedPreferences.Editor editor = sharedpreferences.edit();
            editor.putString(Uimage, stringUri);
            editor.apply();

            if (file2.exists())
                file2.delete();

            try {
                FileOutputStream out = new FileOutputStream(file2);
                assert Croppedbitmap != null;
                Croppedbitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
                out.flush();
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight)
    { // BEST QUALITY MATCH

        //First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);

        // Calculate inSampleSize, Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        int inSampleSize = 1;

        if (height > reqHeight)
        {
            inSampleSize = Math.round((float)height / (float)reqHeight);
        }
        int expectedWidth = width / inSampleSize;

        if (expectedWidth > reqWidth)
        {
            //if(Math.round((float)width / (float)reqWidth) > inSampleSize) // If bigger SampSize..
            inSampleSize = Math.round((float)width / (float)reqWidth);
        }

        options.inSampleSize = inSampleSize;

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;

        return BitmapFactory.decodeFile(path, options);
    }



    /**
     * Validating form
     */

    private boolean submitForm() {
        if (!validateName()) {
            return false;
        }

        if (!validateContact()) {
            return false;
        }

        if (!validateEmail()) {
            return false;
        }

        Snackbar snackbar = Snackbar
                .make(coordinatorLayout, "Saved!", Snackbar.LENGTH_LONG);

        snackbar.show();

        return true;
    }

    private boolean validateName() {
        if (usernameTextView.getText().toString().trim().isEmpty()) {
            inputLayoutName.setError(getString(R.string.err_msg_name));
            requestFocus(usernameTextView);
            return false;
        } else {
            inputLayoutName.setError(null);
        }

        return true;
    }

    private boolean validateEmail() {
        String email = userEmailTextView.getText().toString().trim();

        if (email.isEmpty() || !isValidEmail(email)) {
            inputLayoutEmail.setError(getString(R.string.err_msg_email));
            requestFocus(userEmailTextView);
            return false;
        } else {
            inputLayoutEmail.setError(null);
        }

        return true;
    }

    private boolean validateContact() {
        if (userContactTextView.getText().toString().trim().isEmpty()) {
            inputLayoutContact.setError(getString(R.string.err_msg_contact));
            requestFocus(userContactTextView);
            return false;
        } else {
            inputLayoutContact.setError(null);
        }

        return true;
    }

    private static boolean isValidEmail(String email) {
        return !TextUtils.isEmpty(email) && android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches();
    }

    private void requestFocus(View view) {
        if (view.requestFocus()) {
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        }
    }

    private class MyTextWatcher implements TextWatcher {

        private View view;

        private MyTextWatcher(View view) {
            this.view = view;
        }

        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        public void afterTextChanged(Editable editable) {
            switch (view.getId()) {
                case R.id.username:
                    validateName();
                    break;
                case R.id.useremail:
                    validateEmail();
                    break;
                case R.id.usercontact:
                    validateContact();
                    break;
            }
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.editprofile_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_save:

                if (!submitForm()) {

                    return false;
                }

                SharedPreferences.Editor editor = sharedpreferences.edit();

                TextView usernameTextView = (TextView) findViewById(R.id.username);
                String usernameString = usernameTextView.getText().toString();

                editor.putString(Name, usernameString);
                editor.apply();

                TextView ucontactTV = (TextView) findViewById(R.id.usercontact);
                String uContactS = ucontactTV.getText().toString();

                editor.putString(UContact, uContactS);
                editor.apply();

                TextView uEmailTV = (TextView) findViewById(R.id.useremail);
                String uEmailS = uEmailTV.getText().toString();

                editor.putString(Uemail, uEmailS);
                editor.apply();

                Snackbar snackbar = Snackbar
                        .make(coordinatorLayout, "Saved!", Snackbar.LENGTH_LONG);

                snackbar.show();

                Intent userProfileIntent = new Intent(EditUserProfile.this, UserProfile.class);

                userProfileIntent.putExtra(Name, usernameString);
                userProfileIntent.putExtra(UContact, uContactS);
                userProfileIntent.putExtra(Uemail, uEmailS);

                if (sharedpreferences.contains(stringUri)) {
                    userProfileIntent.putExtra(Uimage, stringUri);
                }

                setResult(RESULT_OK, userProfileIntent);
                finish();

        }
        return true;
    }

}

Solution

  • See if this library helps. https://github.com/IsseiAoki/SimpleCropView

    It can keep the quality of the original image.

    Edit:

    Hmm they may have updated the library. I am using the older library of SimpleCropView. Here is my Implementation.

    For selecting picture from device.:

    Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
    

    Then on Activity Result:

    if (requestCode == PICK_IMAGE_REQUEST && data != null && data.getData() != null) {
    
    
                try {
                    String selectedImagePath = null;
                    Uri selectedImageUri = data.getData();
    
                    if (selectedImageUri.toString().contains("%")) {
                        if (selectedImageUri.toString().startsWith("content://com.google.android.apps.photos.content")) {
                            Log.v("esty", "URI: " + selectedImageUri.toString());
                            selectedImagePath = getPath.getImageUrlWithAuthority(this, selectedImageUri);
    
                        } else {
    
    
                            Log.v("esty", "URI: " + selectedImageUri.toString());
                            String[] UriArray = selectedImageUri.toString().split("%3A");
    
                            String newURIString = "content://media/external/images/media/" + UriArray[1];
                            Uri newURI = Uri.parse(newURIString);
                            Log.v("esty", "URI: " + newURI);
                            selectedImagePath = getPath.getPath(newURI, this);
                        }
                    } else {
                        selectedImagePath = getPath.getPath(selectedImageUri, this);
                    }
    
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                    bitmap1 = BitmapFactory.decodeFile(selectedImagePath, options);
    
                    // MessageBox.Show(this, selectedImagePath);
                    finalFile = new File(selectedImagePath);
                    ProfilePic.setImageBitmap(bitmap1);
                    filename=selectedImagePath.substring(selectedImagePath.lastIndexOf("/")+1);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    

    My SimpleCropView Initialization in OnCreate:

    CropImageView ProfilePic = (CropImageView) findViewById(R.id.cropImageView);
    

    And for getting the Cropped Bitmap:

    final Bitmap croppedImage = ProfilePic.getCroppedBitmap();