Search code examples
imageandroid-studioandroidxandroid-camera2

Compress image using AndroidX


I'm using androidX to take a picture from the camera. As the quality of the image will depend on the camera , larger picture are taking longer time to upload to the server. So there a way for me to compress the image. Note: there is not bitmap and i do not want to convert it bitmap to compress it.

here is how i'm capturing the image.


    private void takePicture() {
        if (imageCapture != null) {
            ByteArrayOutputStream result = new ByteArrayOutputStream();
            getCacheDir();
            imageCapture.takePicture(new ImageCapture.OutputFileOptions.Builder(result).build(),
                    Executors.newSingleThreadExecutor(),
                    new ImageCapture.OnImageSavedCallback() {
                        @Override
                        public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                            File cache = new File(getCacheDir().getAbsolutePath() + "/" + "captured.png" );
                            try (FileOutputStream stream = new FileOutputStream(cache)) {
                                stream.write(result.toByteArray());
                                uploadImage(cache);
                                finish();
                            } catch (Exception e) {
                                Log.e(TAG, "onImageSaved: Exception occurred", e);
                            }
                        }

                        @Override
                        public void onError(@NonNull ImageCaptureException exception) {
                            Log.i(TAG, "onError: ", exception);
                        }

                    });
        }
    }

what would be the best way to compress the image without sacrificing on quality.


Solution

  • I solved the issue by using the below code

     public File compressFile(File file, final int sizeRatio) {
            try {
                // BitmapFactory options to downsize the image
                BitmapFactory.Options o = new BitmapFactory.Options();
                o.inJustDecodeBounds = true;
                o.inSampleSize = 8;
                // factor of downsizing the image
    
                FileInputStream inputStream = new FileInputStream(file);
                BitmapFactory.decodeStream(inputStream, null, o);
                inputStream.close();
    
                // Find the correct scale value. It should be the power of 2.
                int scale = 1;
                while (o.outWidth / scale / 2 >= sizeRatio &&
                        o.outHeight / scale / 2 >= sizeRatio) {
                    scale *= 2;
                }
    
                BitmapFactory.Options o2 = new BitmapFactory.Options();
                o2.inSampleSize = scale;
    
                inputStream = new FileInputStream(file);
                Bitmap selectedBitmap = BitmapFactory.decodeStream(inputStream, null, o2);
                inputStream.close();
    
                FileOutputStream outputStream = new FileOutputStream(file);
                selectedBitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
                Log.i(TAG, "compressFile: size " + Files.size(file.toPath()) / 1024);
                return file;
            } catch (OutOfMemoryError | Exception e) {
                Log.e(TAG, "compressFile: exception during compressor ", e);
                return file;
            }
        }
    

    reference :