0

How can I compress the file size and quality when uploading pictures?

I already finished the upload file to firebase, how to compress the file?

Because when the file size is big, it will slow loading in recyclerview.

So I wanna compress the file.

 Uri imageUri = imageListUri.get(index);
        if(spinner.getSelectedItem().toString().equals(getApplicationContext().getResources().getString(R.string.choose_sub))) {
            AlertDialog alertDialog = new AlertDialog.Builder(this)
                    .setTitle(getApplicationContext().getResources().getString(R.string.alert_error))
                    .setMessage(getApplicationContext().getResources().getString(R.string.choose_sub))
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    }).create();
            alertDialog.show();
        } else if(image_check.equals("ok")) {
            final ProgressDialog progressDialog = new ProgressDialog(this);
            progressDialog.setMessage(getApplicationContext().getResources().getString(R.string.posting));
            progressDialog.show();

            if (imageUri != null) {
                final StorageReference filerefrence = storageReference.child(System.currentTimeMillis()
                        + "." + getFileExtension(imageUri));
                // scaling the image
                int scaleDivider = 1;
                try {
                    Bitmap fullBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
                    int scaleWidth = fullBitmap.getWidth() / scaleDivider;
                    int scaleHeight = fullBitmap.getHeight() / scaleDivider;
                    byte[] downsizedImageBytes =
                            getDownsizedImageBytes(fullBitmap, scaleWidth, scaleHeight);

                    uploadTask = filerefrence.putBytes(downsizedImageBytes);
                } catch (IOException e) {
                    e.printStackTrace();
                }
static public byte[] getDownsizedImageBytes(Bitmap fullBitmap, int scaleWidth, int scaleHeight) throws IOException {

        Bitmap scaledBitmap = Bitmap.createScaledBitmap(fullBitmap, scaleWidth, scaleHeight, true);

        // 2. Instantiate the downsized image content as a byte[]
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

        return baos.toByteArray();
    }

So, is it correct?

try {
                    Bitmap fullBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
                    ByteArrayOutputStream out = new ByteArrayOutputStream();
                    fullBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out); // Here 100 is the quality in percent of the image
                    Bitmap decoded = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));

                    int scaleWidth = fullBitmap.getWidth() / scaleDivider;
                    int scaleHeight = fullBitmap.getHeight() / scaleDivider;
                    byte[] downsizedImageBytes =
                            getDownsizedImageBytes(fullBitmap, scaleWidth, scaleHeight);

                    uploadTask = filerefrence.putBytes(downsizedImageBytes);
                } catch (IOException e) {
                    e.printStackTrace();
                }
SAWYU
  • 119
  • 8

1 Answers1

0

You can do it using the BitmapFactory class like so

Bitmap original = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri)
ByteArrayOutputStream out = new ByteArrayOutputStream();
original.compress(Bitmap.CompressFormat.JPEG, 100, out); // Here 100 is the quality in percent of the image
Bitmap decoded = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));

Note that PNG is already a lossless format so it won't make any difference while compression, if you really want to see the effects use JPEG

Quality Accepts 0 - 100

0 = MAX Compression (Least Quality which is suitable for Small images)

100 = Least Compression (MAX Quality which is suitable for Big images)

Credits to this answer

gtxtreme
  • 1,830
  • 1
  • 13
  • 25
  • Thx, but how to using in array? because I'd used byte[] downsizedImageBytes – SAWYU Aug 04 '21 at 16:19
  • Can you show the contents of the `getDownsizedImageBytes(fullBitmap, scaleWidth,scaleHeight);` method? It is returning a byte array already you can apply your transformation there straightaway and then return a byte array – gtxtreme Aug 04 '21 at 16:27
  • I think you've done it correctly, instead of `100` you can specify the quality you want to compress it to – gtxtreme Aug 05 '21 at 13:03
  • But, I still confuse it, how can I do? I just add ByteArrayOutputStream out = new ByteArrayOutputStream(); original.compress(Bitmap.CompressFormat.JPEG, 100, out); Bitmap decoded = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray())); this three lines? – SAWYU Aug 05 '21 at 13:10
  • Yes that's it, you have to return the byte array of the bitmap after compressing it – gtxtreme Aug 05 '21 at 13:11
  • Have a last question, Bitmap decoded = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray())); , the decoded I need to use where? – SAWYU Aug 05 '21 at 13:37
  • You don't need to use the decoded Bitmap You can pas the byte array directly to the `StorageReference` class. It will take care of the rest Usually `Bitmap` as a consolidated entity is required for operations in Android For sending Data like an image to a server such as Firebase, stream or array of bytes is preferred – gtxtreme Aug 05 '21 at 14:39
  • But, I dont know why the file size is same, when I upload the file then I go to firebase check it. The file size is same in my phone – SAWYU Aug 06 '21 at 15:31
  • https://stackoverflow.com/questions/41611294/how-to-reduce-the-size-of-image-before-uploading-it-to-firebase-storage – gtxtreme Aug 06 '21 at 16:53