安卓图库意图:我如何才能获得和设置原始裁剪图像的全尺寸和良好的质量,而不是缩略图



下面是我的编辑配置文件活动,我为用户提供了一个从库中设置配置文件图片的选项。当用户点击编辑个人资料图片时,它会打开图库,裁剪所选图像,裁剪后的图像将保存在预定义的位置和临时位置,裁剪后图像将设置为个人资料图片。然而,它总是得到缩略图或低质量的图像。图像的质量与我们如何通过uri将图像传递到intent中,然后用getData获取图像uri,然后用setImageUri设置图像的质量相同,因为这样它会给出缩略图,而不是原始图像。这就是为什么我首先尝试保存裁剪后的图像,然后从那里获取它。即使为了避免OOM(内存不足)错误,我也尝试使用inSampleSize、位图工厂选项和所有。。。但最后,我得到的总是相同的缩略图类型的图像质量!

正如标题中所说,我想要的是为userImageView设置的原始裁剪图像,而不是缩略图或低分辨率图像!

还要考虑到我在android开发以及编程、编码等方面都是新手!

任何形式的帮助都将不胜感激!

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;
    }
}

看看这个库是否有帮助。https://github.com/IsseiAoki/SimpleCropView

它可以保持原始图像的质量。

编辑:

嗯,他们可能已经更新了图书馆。我正在使用SimpleCropView的旧库。这是我的实施。

用于从设备中选择图片。:

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

然后是活动结果:

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();
            }
        }

OnCreate:中的SimpleCropView初始化

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

以及获取裁剪位图:

final Bitmap croppedImage = ProfilePic.getCroppedBitmap();

我需要做的只是如下所示的一点更改:

intent.putExtra("outputX", 640);
                intent.putExtra("outputY", 640);

640而不是360,就完成了!我们仍然可以在xml属性中获得360dp的宽度和高度,但在这里调整它会影响图像质量。如前所述,用640取代360,给了我想要的图像质量,而且比我之前得到的要好得多。所以最好在这里保持一个平均值,大多数图像都可以。然而,如果如上所述在这里故意设置的值大于原始图像,则有可能在图像视图内的图像周围具有黑色像素空间。因此,我们必须将大多数图像的平均值也考虑到图像质量。

最新更新