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.
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 :