-1

I am creating a social network application in which users can post images, so when a user uploads its image, it is of very large size and when I am retrieving that image, it is taking too much time with Picasso. Is there any way to compress those images before uploading without significant quality loss, so that they can be retrieved very efficiently and fast. P.S: I am using Firebase as a backend Server.

Here is my code of uploading images.

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

    if(requestCode == Gallery_Pick && resultCode == RESULT_OK && data != null){
        ImageUri = data.getData();
        SelectPostImage.setImageURI(ImageUri);
    }
    super.onActivityResult(requestCode, resultCode, data);
}

final StorageReference filePath = PostImagesRef.child("Post Images").child(ImageUri.getLastPathSegment() + postRandomName + ".jpg");

    final UploadTask uploadTask = filePath.putFile(ImageUri);

    uploadTask.addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            String message = e.toString();
            Toast.makeText(PostActivity.this, "Some Error Occured"+message, Toast.LENGTH_SHORT).show();
            loadingBar.dismiss();
        }
    }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            Toast.makeText(PostActivity.this, "Image Uploaded Successfully", Toast.LENGTH_SHORT).show();
            Task<Uri> urlTask = uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
                @Override
                public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
                    if(!task.isSuccessful()){
                        throw task.getException();
                    }
                    downloadImageUrl = filePath.getDownloadUrl().toString();

                    return filePath.getDownloadUrl();
                }
            }).addOnCompleteListener(new OnCompleteListener<Uri>() {
                @Override
                public void onComplete(@NonNull Task<Uri> task) {
                    if(task.isSuccessful()){

                        downloadImageUrl = task.getResult().toString();
                        Toast.makeText(PostActivity.this, "Saved To Database Successfully", Toast.LENGTH_SHORT).show();
                        SavingPostInformationToDatabase();

                    }
                }
            });
        }
    });

Please help me. Any Help or Suggestion Would Be Appreciable. Thanks In Advance.!! :)

Ankur Singhal
  • 57
  • 2
  • 7

2 Answers2

1

You can simple using Glide to resize your image and using that image to upload to firebase

Glide.with(requireActivity())
                .asBitmap()
                .override(YOUR_IMAGE_SIZE, YOUR_IMAGE_SIZE)
                .load(uri)
                .into(object : CustomTarget<Bitmap>() {
                    override fun onResourceReady(
                        resource: Bitmap,
                        transition: Transition<in Bitmap>?
                    ) {

                        // using bitmapToByte(resource) -> byte
                        // using filePath.putBytes(data) -> uploadTask
                         val filePath = PostImagesRef.child("Post Images").child(ImageUri.getLastPathSegment() + postRandomName + ".jpg")

                         val uploadTask = filePath.putBytes(bitmapToByte(resource))
                    }

                    override fun onLoadCleared(placeholder: Drawable?) {
                        // this is called when imageView is cleared on lifecycle call or for
                        // some other reason.
                        // if you are referencing the bitmap somewhere else too other than this imageView
                        // clear it here as you can no longer have the bitmap
                    }
                })

bitmapToByte function

 fun bitmapToByte(bitmap: Bitmap): ByteArray {
    val stream = ByteArrayOutputStream()
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream)
    return stream.toByteArray()
}

hope this helps

GianhTran
  • 3,443
  • 2
  • 22
  • 42
1

You can try this way. Change this onActivityResult.

if(requestCode == Gallery_Pick && resultCode == RESULT_OK && data != null) {
            try {
                Uri imageUri = imageReturnedIntent.getData();
                InputStream imageStream = getContentResolver().openInputStream(imageUri);
                Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);

                selectedImage = getResizedBitmap(selectedImage, 400,300);// 400 and 300 height and width, replace with desired size

                imageView.setImageBitmap(selectedImage); // your desired image


            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

Here is the getResizedBitmap method you need.

    public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
    int width = bm.getWidth();
    int height = bm.getHeight();
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;

    // create a matrix for the manipulation
    Matrix matrix = new Matrix();

    // resize the bit map
    matrix.postScale(scaleWidth, scaleHeight);

    // recreate the new Bitmap
    Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);

    return resizedBitmap;
}
Noban Hasan
  • 593
  • 1
  • 7
  • 21
  • It Is Surely Compressing the size but not that much. It is Converting 9mb image size to max 6 MB. I want it in kb so that it loads super quick.Any Suggestions? BTW Thanks For This Help. – Ankur Singhal Jun 29 '20 at 11:42
  • Are you telling that `selectedImage = getResizedBitmap(selectedImage, 400,300);// 400 and 300 height and width, replace with desired size` would deliver a file of 6MB ? We do not believe you. – blackapps Jun 29 '20 at 12:20
  • Yes, I have uploaded a file of 7.15 MB and it just gets converted to 6.82 MB. Just this much it is compressing the image. Do you have any other suggestion to compress it even further with lossless quality? – Ankur Singhal Jun 29 '20 at 12:31
  • @AnkurSinghal maybe this answer should help you more https://stackoverflow.com/a/823966/8332511 – Noban Hasan Jun 29 '20 at 14:11