简体   繁体   English

在这种情况下发送到 Firebase 时如何压缩图像?

[英]How can I compress an image when sending to Firebase in this situation?

I am developing an app for android devices like WhatsApp.我正在为 WhatsApp 等 android 设备开发应用程序。 It is already in a very advanced state and I am correcting minor problems that I was encountering.它已经处于非常先进的状态,我正在纠正我遇到的小问题。 But this one I am having difficulty solving in particular.但是这个我特别难以解决。

The goal would be to compress the profile and cover photo to take up less space on Firebase Storage.目标是压缩个人资料和封面照片,以减少 Firebase 存储上的空间。 Compression would then have to work for both Profile and Cover Image.压缩必须同时适用于配置文件和封面图像。

 private boolean checkStoragePermissions(){
    //check if storage permission is enabled or not
    //return true if enabled
    //return false if not enabled
    boolean result = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
            == (PackageManager.PERMISSION_GRANTED);
    return result;
}
private void requestStoragePermission(){
    //request runtime storage permission
    requestPermissions(storagePermissions, STORAGE_REQUEST_CODE);
}


private boolean checkCameraPermissions(){
    //check if storage permission is enabled or not
    //return true if enabled
    //return false if not enabled
    boolean result = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
            == (PackageManager.PERMISSION_GRANTED);

    boolean result1 = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
            == (PackageManager.PERMISSION_GRANTED);
    return result && result1;
}
private void requestCameraPermission(){
    //request runtime storage permission
    requestPermissions(cameraPermissions, CAMERA_REQUEST_CODE);
}

private void showEditProfileDialog() {
    /*Show dialog containing options
    * 1) Edit Profile Picture
    * 2) Edit Cover Photo
    * 3) Edit Name
    * 4) Edit Profile Status*/

    //options to show in dialog
    String options[] = {"Edit Profile Picture", "Edit Cover Photo", "Edit Name", "Edit Profile Status"};
    //alert dialog
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    //set title
    builder.setTitle("Profile Settings");
    //set items to dialog
    builder.setItems(options, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            //handle dialog items clicks
            if(which == 0){
                //edit profile clicked
                pd.setMessage("Updating Profile Picture");
                profileOrCoverPhoto = "image"; //i.e. changing profile picture, make sure to assign same value
                showImagePicDialog();
            }
            else if (which == 1){
                //edit cover clicked
                pd.setMessage("Updating Cover Image");
                profileOrCoverPhoto = "cover"; //i.e. changing cover photo+, make sure to assign same value
                showImagePicDialog();
            }
            else if (which == 2){
                //edit name clicked
                pd.setMessage("Updating Name");
                //calling method and pass key "name" as parameter to update its value in database
                showNameProfileStatusUpdateDialog("name");
            }
            else if (which == 3){
                //edit phone clicked
                pd.setMessage("Updating Profile Status");
                showNameProfileStatusUpdateDialog("profileStatus");
            }
        }
    });
    //create and show dialog
    builder.create().show();
}

private void showNameProfileStatusUpdateDialog(final String key) {
    /*parameter "key" will contain value name and phone*/
    //custom dialog
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme);
    builder.setTitle("Update");
    //set layout of dialog
    LinearLayout linearLayout = new LinearLayout(getActivity());
    linearLayout.setOrientation(LinearLayout.VERTICAL);
    linearLayout.setPadding(10,10,10,10);
    //add edit text
    final EditText editText = new EditText(getActivity());
    editText.setHint("Write here");
    linearLayout.addView(editText);

    builder.setView(linearLayout);

    //add button to dialog to update
    builder.setPositiveButton("Update", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            //input text from edittext
            final String value = editText.getText().toString().trim();
            if (!TextUtils.isEmpty(value)){
                pd.show();
                HashMap<String, Object> result = new HashMap<>();
                result.put(key, value);

                databaseReference.child(user.getUid()).updateChildren(result)
                        .addOnSuccessListener(new OnSuccessListener<Void>() {
                            @Override
                            public void onSuccess(Void aVoid) {
                                //updated, dismiss progress
                                pd.dismiss();
                                Toast.makeText(getActivity(), "Updated", Toast.LENGTH_SHORT).show();

                            }
                        })
                        .addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                //failed updating progress. dismiss progress and show error message
                                pd.dismiss();
                                Toast.makeText(getActivity(), ""+e.getMessage(), Toast.LENGTH_SHORT).show();
                            }
                        });

                //if user edit his name, also change it from hist posts
                if (key.equals("name")){
                    DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Posts");
                    Query query = ref.orderByChild("uid").equalTo(uid);
                    query.addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                            for (DataSnapshot ds: dataSnapshot.getChildren()){
                                String child = ds.getKey();
                                dataSnapshot.getRef().child(child).child("uName").setValue(value);
                            }
                        }

                        @Override
                        public void onCancelled(@NonNull DatabaseError databaseError) {

                        }
                    });

                    //update name in current users comments on posts
                    ref.addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                            for (DataSnapshot ds: dataSnapshot.getChildren()){
                                String child = ds.getKey();
                                if (dataSnapshot.child(child).hasChild("Comments")){
                                    String child1 = ""+dataSnapshot.child(child).getKey();
                                    Query child2 = FirebaseDatabase.getInstance().getReference("Posts").child(child1).child("Comments").orderByChild(uid).equalTo(uid);
                                    child2.addValueEventListener(new ValueEventListener() {
                                        @Override
                                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                            for (DataSnapshot ds: dataSnapshot.getChildren()){
                                                String child = ds.getKey();
                                                dataSnapshot.getRef().child(child).child("uName").setValue(value);

                                            }
                                        }

                                        @Override
                                        public void onCancelled(@NonNull DatabaseError databaseError) {

                                        }
                                    });
                                }
                            }
                        }

                        @Override
                        public void onCancelled(@NonNull DatabaseError databaseError) {

                        }
                    });
                }
            }
            else{
                Toast.makeText(getActivity(), "Please enter"+key, Toast.LENGTH_SHORT).show();
            }
        }
    });
    //add button to dialog to cancel the update
    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {

        }
    });
    //create and show dialog
    builder.create().show();
}

private void showImagePicDialog() {
    //show dialog containing options camera and gallery to pick the image

    String options[] = {"Camera", "Gallery"};
    //alert dialog
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    //set title
    builder.setTitle("Pick Image From");
    //set items to dialog
    builder.setItems(options, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            //handle dialog items clicks
            if(which == 0){
                //camera clicked
                if (!checkCameraPermissions()){
                    requestCameraPermission();
                }
                else {
                    pickFromCamera();
                }
            }
            else if (which == 1){
                //gallery clicked
                if (!checkStoragePermissions()){
                    requestStoragePermission();
                }
                else{
                    pickFromGallery();
                }
            }
        }
    });
    //create and show dialog
    builder.create().show();


}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    /*This method called when user press Allow or Deny from permission request dialog
    * here we will handle permissions cases (allowed & denied)*/

    switch (requestCode){
        case CAMERA_REQUEST_CODE: {
            //picking from camera, first check if camera and storage permission allowed or not
            if (grantResults.length > 0){
                boolean cameraAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                boolean writeStorageAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
                if (cameraAccepted && writeStorageAccepted){
                    //permissions enabled
                    pickFromCamera();
                }
                else{
                    //permission denied
                    Toast.makeText(getActivity(), "Please enable camera and storage permissions", Toast.LENGTH_SHORT).show();
                }
            }
        }
        break;
        case STORAGE_REQUEST_CODE: {

            //picking from gallery, first check if storage permission allowed or not
            if (grantResults.length > 0){
                boolean writeStorageAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                if (writeStorageAccepted){
                    //permissions enabled
                    pickFromGallery();
                }
                else{
                    //permission deniad
                    Toast.makeText(getActivity(), "Please enable storage permissions", Toast.LENGTH_SHORT).show();
                }
            }
        }
        break;
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    /*this method will be called after picking image from camera or gallery*/
    if (resultCode == RESULT_OK){

        if (requestCode == IMAGE_PICK_GALLERY_CODE){
            //image is picked from gallery, get uri of image
            image_uri = data.getData();

            uploadProfileCoverPhoto(image_uri);
        }
        if (requestCode == IMAGE_PICK_CAMERA_CODE){
            //image is picked from camera, get uri of image

            uploadProfileCoverPhoto(image_uri);
        }
    }

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

private void uploadProfileCoverPhoto(final Uri uri) {
    //show progress
    pd.show();
    /*Instead of creating separate function for profile picture and cover photo this will work in the same function*/

    //path and name of image to be stored in firebase storage
    String filePathAndName = storagePath+ ""+ profileOrCoverPhoto +"_"+ user.getUid();

    StorageReference storageReference2nd = storageReference.child(filePathAndName);
    storageReference2nd.putFile(uri)
            .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                    //image uploaded to storage, now get its url and store in users database
                    Task<Uri> uriTask = taskSnapshot.getStorage().getDownloadUrl();
                    while (!uriTask.isSuccessful());
                    final Uri downloadUri = uriTask.getResult();

                    //check if image is uploading or not and url received
                    if (uriTask.isSuccessful()){
                        //image uploaded
                        //add/update url in users database
                        HashMap<String, Object> results = new HashMap<>();
                        /*first parameter is profileorcover photo thas has value "image" or "cover" which are keys in users database where url of the image
                        * be saved in of them
                        * Second parameter contains the url of the image stored in firebase storage, this url will be saved as value against key "image" or "cover"*/
                        results.put(profileOrCoverPhoto, downloadUri.toString());

                        databaseReference.child(user.getUid()).updateChildren(results)
                                .addOnSuccessListener(new OnSuccessListener<Void>() {
                                    @Override
                                    public void onSuccess(Void aVoid) {
                                        //URL IN DATA BASE of user is add succesfully
                                        //dismiss progress bar
                                        pd.dismiss();
                                        Toast.makeText(getActivity(), "Image Updated.", Toast.LENGTH_SHORT).show();
                                    }
                                })
                                .addOnFailureListener(new OnFailureListener() {
                                    @Override
                                    public void onFailure(@NonNull Exception e) {
                                        //error adding url in database of user
                                        //dismiss progress bar
                                        pd.dismiss();
                                        Toast.makeText(getActivity(), "An error occurred updating the image.", Toast.LENGTH_SHORT).show();
                                    }
                                });

                        //if user edit his name, also change it from hist posts
                        if (profileOrCoverPhoto.equals("image")){

                            DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Posts");
                            Query query = ref.orderByChild("uid").equalTo(uid);
                            query.addValueEventListener(new ValueEventListener() {
                                @Override
                                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                    for (DataSnapshot ds: dataSnapshot.getChildren()){
                                        String child = ds.getKey();
                                        dataSnapshot.getRef().child(child).child("uDp").setValue(downloadUri.toString());
                                    }
                                }

                                @Override
                                public void onCancelled(@NonNull DatabaseError databaseError) {

                                }
                            });
                            //update user image in current users comments on posts
                            ref.addListenerForSingleValueEvent(new ValueEventListener() {
                                @Override
                                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                    for (DataSnapshot ds: dataSnapshot.getChildren()){
                                        String child = ds.getKey();
                                        if (dataSnapshot.child(child).hasChild("Comments")){
                                            String child1 = ""+dataSnapshot.child(child).getKey();
                                            Query child2 = FirebaseDatabase.getInstance().getReference("Posts").child(child1).child("Comments").orderByChild(uid).equalTo(uid);
                                            child2.addValueEventListener(new ValueEventListener() {
                                                @Override
                                                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                                    for (DataSnapshot ds: dataSnapshot.getChildren()){
                                                        String child = ds.getKey();
                                                        dataSnapshot.getRef().child(child).child("uDp").setValue(downloadUri.toString());

                                                    }
                                                }

                                                @Override
                                                public void onCancelled(@NonNull DatabaseError databaseError) {

                                                }
                                            });
                                        }
                                    }
                                }

                                @Override
                                public void onCancelled(@NonNull DatabaseError databaseError) {

                                }
                            });

                        }
                    }
                    else{
                        //error
                        pd.dismiss();
                        Toast.makeText(getActivity(), "An error has occurred.", Toast.LENGTH_SHORT).show();
                    }
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    //there were some error, get and show error message, dismiss progress dialog
                    pd.dismiss();
                    Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
}

private void pickFromCamera() {
    //intent of picking image from device camera
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.TITLE, "Temp Pic");
    values.put(MediaStore.Images.Media.DESCRIPTION, "Temp Description");
    //put image uri
    image_uri = getActivity().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

    //intent to start camera
    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
    startActivityForResult(cameraIntent, IMAGE_PICK_CAMERA_CODE);
}

private void pickFromGallery() {
    //pick from gallery
    Intent galleryIntent = new Intent(Intent.ACTION_PICK);
    galleryIntent.setType("image/*");
    startActivityForResult(galleryIntent, IMAGE_PICK_GALLERY_CODE);
}

I'm using this object to compress an image to 1Mo max :我正在使用这个对象将图像压缩到 1Mo max :

/**
 * Definition of the BitmapUtils object.
 */
object BitmapUtils {
    const val ONE_KO = 1024
    const val ONE_MO = ONE_KO * ONE_KO

    /**
     * Compress, if needed, an image file to be lower than or equal to 1 Mo
     *
     * @param filePath Image file path
     *
     * @return Stream containing data of the compressed image. Can be null
     */
    fun compressedImageFile(filePath: String): InputStream? {
        var quality = 100
        var inputStream: InputStream? = null
        if (filePath.isNotEmpty()) {
            var bufferSize = Integer.MAX_VALUE
            val byteArrayOutputStream = ByteArrayOutputStream()
            try {
                val bitmap = BitmapFactory.decodeFile(filePath)
                do {
                    if (bitmap != null) {
                        byteArrayOutputStream.reset()
                        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream)
                        bufferSize = byteArrayOutputStream.size()
                        logD { "quality: $quality -> length: $bufferSize" }
                        quality -= 10
                    }
                } while (bufferSize > ONE_MO)
                inputStream = ByteArrayInputStream(byteArrayOutputStream.toByteArray())
                byteArrayOutputStream.close()
            } catch (e: Exception) {
                logE { "Exception when compressing file image: ${e.message}" }
            }
        }
        return inputStream
    }
}

Ok.好的。 I was able to adapt my code to match what I wanted.我能够调整我的代码以匹配我想要的。 Here is the result.这是结果。

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    //this method will be called after picking image from camera or gallery

    if (requestCode == IMAGE_PICK_GALLERY_CODE && resultCode ==  RESULT_OK){
        Uri imagePath = data.getData();

        CropImage.activity(imagePath)
                .setGuidelines(CropImageView.Guidelines.ON)
                .start(ProfileSettingsActivity.this);
    }

    if (requestCode == IMAGE_PICK_CAMERA_CODE && resultCode ==  RESULT_OK){

        CropImage.activity(image_rui)
                .setGuidelines(CropImageView.Guidelines.ON)
                .start(ProfileSettingsActivity.this);
    }

    if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE){

        CropImage.ActivityResult result = CropImage.getActivityResult(data);


        if (resultCode == RESULT_OK){

            image_rui = result.getUri();
            //Log.d(TAG, "onActivityResult: Image Uri " + image_rui.toString());


            File actualImage = new File(image_rui.getPath());

            try {
                Bitmap compressedImage = new Compressor(this)
                        .setMaxWidth(250)
                        .setMaxHeight(250)
                        .setQuality(25)
                        .compressToBitmap(actualImage);

                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                compressedImage.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                byte[] final_image = baos.toByteArray();

                //show progress
                /*Instead of creating separate function for profile picture and cover photo this will work in the same function*/

                //path and name of image to be stored in firebase storage
                String filePathAndName = storagePath+ ""+ profileOrCoverPhoto +"_"+ user.getUid();

                StorageReference storageReference2nd = storageReference.child(filePathAndName);

                UploadTask uploadTask = storageReference2nd.putBytes(final_image);

                uploadTask
                        .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                            @Override
                            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                                //image uploaded to storage, now get its url and store in users database
                                Task<Uri> uriTask = taskSnapshot.getStorage().getDownloadUrl();
                                while (!uriTask.isSuccessful());
                                final Uri downloadUri = uriTask.getResult();

                                //check if image is uploading or not and url received
                                if (uriTask.isSuccessful()){
                                    //image uploaded
                                    //add/update url in users database
                                    HashMap<String, Object> results = new HashMap<>();
                                    /*first parameter is profileorcover photo thas has value "image" or "cover" which are keys in users database where url of the image
                                     * be saved in of them
                                     * Second parameter contains the url of the image stored in firebase storage, this url will be saved as value against key "image" or "cover"*/
                                    results.put(profileOrCoverPhoto, downloadUri.toString());

                                    databaseReference.child(user.getUid()).updateChildren(results)
                                            .addOnSuccessListener(new OnSuccessListener<Void>() {
                                                @Override
                                                public void onSuccess(Void aVoid) {
                                                    //URL IN DATA BASE of user is add succesfully
                                                    //dismiss progress bar
                                                    pd.dismiss();
                                                    Toast.makeText(ProfileSettingsActivity.this, "Image Updated.", Toast.LENGTH_SHORT).show();
                                                }
                                            })
                                            .addOnFailureListener(new OnFailureListener() {
                                                @Override
                                                public void onFailure(@NonNull Exception e) {
                                                    //error adding url in database of user
                                                    //dismiss progress bar
                                                    pd.dismiss();
                                                    Toast.makeText(ProfileSettingsActivity.this, "An error occurred updating the image.", Toast.LENGTH_SHORT).show();
                                                }
                                            });

                                    //if user edit his name, also change it from hist posts
                                    if (profileOrCoverPhoto.equals("image")){

                                        DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Posts");
                                        Query query = ref.orderByChild("uid").equalTo(uid);
                                        query.addValueEventListener(new ValueEventListener() {
                                            @Override
                                            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                                for (DataSnapshot ds: dataSnapshot.getChildren()){
                                                    String child = ds.getKey();
                                                    dataSnapshot.getRef().child(child).child("uDp").setValue(downloadUri.toString());
                                                }
                                            }

                                            @Override
                                            public void onCancelled(@NonNull DatabaseError databaseError) {

                                            }
                                        });
                                        //update user image in current users comments on posts
                                        ref.addListenerForSingleValueEvent(new ValueEventListener() {
                                            @Override
                                            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                                for (DataSnapshot ds: dataSnapshot.getChildren()){
                                                    String child = ds.getKey();
                                                    if (dataSnapshot.child(child).hasChild("Comments")){
                                                        String child1 = ""+dataSnapshot.child(child).getKey();
                                                        Query child2 = FirebaseDatabase.getInstance().getReference("Posts").child(child1).child("Comments").orderByChild(uid).equalTo(uid);
                                                        child2.addValueEventListener(new ValueEventListener() {
                                                            @Override
                                                            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                                                for (DataSnapshot ds: dataSnapshot.getChildren()){
                                                                    String child = ds.getKey();
                                                                    dataSnapshot.getRef().child(child).child("uDp").setValue(downloadUri.toString());

                                                                }
                                                            }

                                                            @Override
                                                            public void onCancelled(@NonNull DatabaseError databaseError) {

                                                            }
                                                        });
                                                    }
                                                }
                                            }

                                            @Override
                                            public void onCancelled(@NonNull DatabaseError databaseError) {

                                            }
                                        });

                                    }
                                }
                                else{
                                    //error
                                    pd.dismiss();
                                    Toast.makeText(ProfileSettingsActivity.this, "An error has occurred.", Toast.LENGTH_SHORT).show();
                                }
                            }
                        })
                        .addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                //there were some error, get and show error message, dismiss progress dialog
                                pd.dismiss();
                                Toast.makeText(ProfileSettingsActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                            }
                        });
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM