Our first blog post on How to create an Android app for image compression, resizing, and filtering from scratch focuses on the scope and content of the Android project.
In this tutorial, we will learn how to compress an image in Android without losing quality.
If you need to compress an image file in Android, this tutorial is for you.
There are different compression options available with image compression in Android.
Using BitmapFactory.Options
BitmapFactory.Options is a class that provides several options for manipulating images. One of these options is the “inSampleSize” property, which can reduce the image’s resolution and its size. You can use this property to compress the image while decoding it.
Below is a simple code example in Android.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2; // Set the inSampleSize value as per your requirement
Bitmap compressedBitmap = BitmapFactory.decodeFile(filePath, options);
Bitmap.compress Method
The Bitmap class in Android provides a `compress()` method which can be used to compress an image. This method allows you to specify the image format (e.g., JPEG, PNG), the quality, and an output stream to write the compressed image to.
Below is a simple code example in Android.
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);
byte[] imageData = baos.toByteArray();
Using third-party libraries
There are several third-party libraries available that offer more advanced image compression techniques. These libraries often provide options to control the compression level, image dimensions, and quality. Some popular libraries include Glide, Picasso, and Compressor. You can use these libraries in your project using Gradle and follow their documentation to compress images.
- implementation ‘com.github.bumptech.glide:glide:4.11.0’
- implementation ‘com.squareup.picasso:picasso:2.5.2’
- implementation ‘id.zelory:compressor:3.0.0’
The method you choose depends on your specific requirements and preferences.
Since we are working on different image manipulation options in Android, we will use the compressor third-party library. There is no need to reinvent the wheel.
Image Compression UI
Below is the user interface for image compression in Andriod.
- Select the Compress item on the list
- Click the image picker button to select an image.
- Choose an image compression option and click the save button.
Create Android Project
I will not cover how to create a new Android Project in Android Studio. There are lots of tutorials out there that have already covered it.
This is a Java Android project. You can convert it to Kotlin if you prefer Kotlin over Java.
I will use the details below in this project. Feel free to choose a name of your choice.
App Name: Image Compress & Resize
Package Name: com.istoby
Language: Java
Now that we have created a new Android Project, let’s see what we will develop. I have added some screenshots below.
Android Image Tool List Page
First, we will create a list of image tools in this project using a Recyclerview.
- Create a new Activity Page and use any name of your choice.
- Add a Recycleview in the layout file of the Activity page.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/bg_color"
android:layout_margin="8dp"
tools:context=".home.ui.tools.PhotoToolFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/image_tool_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:scrollbars="none"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Open the Activity page and add the below code.
public class PhotoToolFragment extends Fragment {
private static final String TAG = PhotoToolFragment.class.getSimpleName();
private FragmentPhotoToolBinding binding;
private RecyclerView imageToolList;
private SmartRecyclerAdapter smartRecyclerAdapter;
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentPhotoToolBinding.inflate(inflater, container, false);
View root = binding.getRoot();
imageToolList = binding.imageToolList;
List<ImageToolModel> data = DataUtils.fetchImageToolOptions();
setUpImageTools(data);
return root;
}
private void setUpImageTools(List<ImageToolModel> data){
smartRecyclerAdapter = SmartRecyclerAdapter
.items(data)
.map(ImageToolModel.class, ImageToolViewHolder.class)
.setLayoutManager(new GridLayoutManager(requireActivity(), 2))
.addViewEventListener((OnImageToolItemClickListener) (view, actionId, position) -> {
ImageToolModel model = (ImageToolModel) data.get(position);
Type type = new TypeToken<ImageToolModel>(){}.getType();
String param = new Gson().toJson(model, type);
String optionName = model.getToolName();
viewImageOption(optionName);
})
.into(imageToolList);
}
private void viewImageOption(String param){
Intent imageToolIntent = null;
if(param.equals("Resize")){
imageToolIntent = new Intent(requireActivity(), ResizeImageActivity.class);
}
if (param.equals("Compress")) {
imageToolIntent = new Intent(requireActivity(), CompressImageActivity.class);
}
if (param.equals("Crop")) {
imageToolIntent = new Intent(requireActivity(), CropImageActivity.class);
}
if (param.equals("Convert")) {
imageToolIntent = new Intent(requireActivity(), ConvertImageActivity.class);
}
if (param.equals("Filter")) {
imageToolIntent = new Intent(requireActivity(), FilterImageActivity.class);
}
if (param.equals("Base64 Encode")) {
imageToolIntent = new Intent(requireActivity(), CipherImageActivity.class);
}
if (param.equals("Draw")) {
imageToolIntent = new Intent(requireActivity(), DrawImageActivity.class);
}
if (param.equals("Image Background")) {
imageToolIntent = new Intent(requireActivity(), BackgroundImageActivity.class);
}
if (param.equals("Compare Images")) {
imageToolIntent = new Intent(requireActivity(), CompareImageActivity.class);
}
if (param.equals("Pixelate")) {
imageToolIntent = new Intent(requireActivity(), PixelateImageActivity.class);
}
if (param.equals("Sketch")) {
imageToolIntent = new Intent(requireActivity(), SketchImageActivity.class);
}
if (param.equals("Image To Ascii")) {
imageToolIntent = new Intent(requireActivity(), AsciiImageActivity.class);
}
if (param.equals("Combine Images")) {
imageToolIntent = new Intent(requireActivity(), CombineImagesActivity.class);
}
if (param.equals("Load Image Online")) {
imageToolIntent = new Intent(requireActivity(), LoadImageOnlineActivity.class);
}
if (param.equals("Zoom")) {
imageToolIntent = new Intent(requireActivity(), ZoomImageActivity.class);
}
if (param.equals("Grid Image")) {
imageToolIntent = new Intent(requireActivity(), GridImageActivity.class);
}
if (param.equals("Erase Background")) {
imageToolIntent = new Intent(requireActivity(), EraseBackgroundActivity.class);
}
if (param.equals("Image Watermark")) {
imageToolIntent = new Intent(requireActivity(), WatermarkImageActivity.class);
}
if (param.equals("Image To Text")) {
imageToolIntent = new Intent(requireActivity(), ImageToTextActivity.class);
}
if (param.equals("Image To PDF")) {
imageToolIntent = new Intent(requireActivity(), ImageToPDFActivity.class);
}
if(imageToolIntent != null){
imageToolIntent.putExtra(ConstantUtils.IMAGE_TOOL_ITEM, param);
startActivity(imageToolIntent);
Bungee.slideLeft(requireActivity());
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
From the code below, we obtained an instant of the Recyclerview.
Add the SmartRecyclerAdapter library in your project build.gradle page.
The SmartRecyclerAdapter library connects the Recycleview with the data source.
Create a Model class and a ViewHolder class, then add this code to them.
ImageToolModel Class
public class ImageToolModel {
private static final String TAG = ImageToolModel.class.getSimpleName();
private int toolIcon;
private String toolName;
public ImageToolModel(int toolIcon, String toolName) {
this.toolIcon = toolIcon;
this.toolName = toolName;
}
public int getToolIcon() {
return toolIcon;
}
public void setToolIcon(int toolIcon) {
this.toolIcon = toolIcon;
}
public String getToolName() {
return toolName;
}
public void setToolName(String toolName) {
this.toolName = toolName;
}
}
ImageToolViewHolder Class
public class ImageToolViewHolder extends SmartViewHolder<ImageToolModel> {
private static final String TAG = ImageToolViewHolder.class.getSimpleName();
private AppCompatImageView toolIcon;
private AppCompatTextView toolName;
public ImageToolViewHolder(ViewGroup parentView) {
super(LayoutInflater.from(parentView.getContext()).inflate(R.layout.image_tool_item_layout, parentView, false));
toolIcon = (AppCompatImageView) itemView.findViewById(R.id.image_tool_icon);
toolName = (AppCompatTextView) itemView.findViewById(R.id.image_tool_name);
}
@Override
public void bind(ImageToolModel item) {
toolIcon.setImageResource(item.getToolIcon());
toolName.setText(item.getToolName());
}
}
Compile and install the code to your device. If there is no error, you will see a screenshot like below.
List Item Click Listener Event
Create an Interface class and use a name of your choice.
Add the code below to this page.
public interface OnImageToolItemClickListener extends OnItemClickListener {
@NonNull
@Override
default Class<? extends SmartViewHolder> getViewHolderType() {
return ImageToolViewHolder.class;
}
}
Go to the SmartRecyclerviewAdapter and add it as a click listener callback.
Add an Intent that navigates to the ImageCompressActivity page.
Image Compression Activity XML Layout File
Open this layout file, copy and paste the code to the file.
This layout file does not need any explanation apart from the toggle button. Add this line to build.gradle to make it work.
implementation 'nl.bryanderidder:themed-toggle-button-group:1.4.1'
Layout Code
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/lighter"
tools:context=".home.ui.tools.featuresUI.CompressImageActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/adview_wrapper"
android:scrollbars="none">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:id="@+id/image_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="4dp"
app:cardUseCompatPadding="true"
app:cardCornerRadius="16dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="220dp"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/selected_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/click_to_upload_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="CLICK TO UPLOAD IMAGE"
android:textStyle="bold"
android:textSize="16sp"
android:padding="16dp"/>
</FrameLayout>
</androidx.cardview.widget.CardView>
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/feature_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardUseCompatPadding="true"
app:cardCornerRadius="8dp"
android:layout_marginEnd="4dp"
android:layout_marginStart="4dp"
android:elevation="2dp"
android:layout_marginTop="8dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dp"
android:orientation="vertical">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Filename: "
android:textStyle="bold"
android:layout_marginEnd="12dp"
android:textColor="@color/black"
android:textSize="15sp"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/selected_image_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"
android:textSize="15sp"
android:layout_marginBottom="12dp"
android:textColor="@color/black"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="File Size: "
android:textStyle="bold"
android:layout_marginEnd="12dp"
android:textColor="@color/black"
android:textSize="15sp"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/selected_image_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textSize="15sp"
android:textColor="@color/black"/>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardUseCompatPadding="true"
app:cardCornerRadius="8dp"
android:layout_marginEnd="4dp"
android:layout_marginStart="4dp"
android:elevation="2dp"
android:layout_marginTop="8dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dp"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Image Format"
android:textStyle="bold"
android:textSize="15sp"
android:layout_marginBottom="18dp"
android:textColor="@color/black"/>
<nl.bryanderidder.themedtogglebuttongroup.ThemedToggleButtonGroup
android:id="@+id/file_format_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:justifyContent="center">
<nl.bryanderidder.themedtogglebuttongroup.ThemedButton
android:id="@+id/image_png"
android:layout_width="wrap_content"
android:layout_height="38dp"
app:toggle_selectedBackgroundColor="@color/my_accent"
app:toggle_selectedTextColor="@android:color/black"
app:toggle_text="PNG" />
<nl.bryanderidder.themedtogglebuttongroup.ThemedButton
android:id="@+id/image_jpg"
android:layout_width="wrap_content"
android:layout_height="38dp"
app:toggle_selectedBackgroundColor="@color/my_accent"
app:toggle_selectedTextColor="@android:color/black"
app:toggle_text="JPG" />
<nl.bryanderidder.themedtogglebuttongroup.ThemedButton
android:id="@+id/image_webp"
android:layout_width="wrap_content"
android:layout_height="38dp"
app:toggle_selectedBackgroundColor="@color/my_accent"
app:toggle_selectedTextColor="@android:color/black"
app:toggle_text="WEBP" />
<nl.bryanderidder.themedtogglebuttongroup.ThemedButton
android:id="@+id/image_bmp"
android:layout_width="wrap_content"
android:layout_height="38dp"
app:toggle_selectedBackgroundColor="@color/my_accent"
app:toggle_selectedTextColor="@android:color/black"
app:toggle_text="BMP" />
</nl.bryanderidder.themedtogglebuttongroup.ThemedToggleButtonGroup>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardUseCompatPadding="true"
app:cardCornerRadius="8dp"
android:layout_marginEnd="4dp"
android:layout_marginStart="4dp"
android:elevation="2dp"
android:layout_marginTop="8dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="12dp">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="18dp"
android:text="Compress Options"
android:textColor="@color/black"
android:textSize="15sp"
android:textStyle="bold" />
<RadioGroup
android:id="@+id/compression_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatRadioButton
android:id="@+id/without_compression"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Without Compression"
android:textColor="@color/black" />
<androidx.appcompat.widget.AppCompatRadioButton
android:id="@+id/auto_compression"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Auto Compression"
android:textColor="@color/black" />
<androidx.appcompat.widget.AppCompatRadioButton
android:id="@+id/length_compression"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Compression by Length"
android:textColor="@color/black" />
<androidx.appcompat.widget.AppCompatRadioButton
android:id="@+id/size_compression"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Compression by Length"
android:textColor="@color/black" />
</RadioGroup>
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/image_length_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:background="@drawable/border_corner"
android:hint="Image length"
android:inputType="number"
android:padding="12dp"
android:visibility="gone" />
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/image_size_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:background="@drawable/border_corner"
android:hint="Image Size (KB)"
android:inputType="number"
android:padding="12dp"
android:visibility="gone" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.cardview.widget.CardView>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</ScrollView>
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/adview_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fafafa"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:orientation="vertical">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="vertical">
</androidx.appcompat.widget.LinearLayoutCompat>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:padding="12dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"
android:layout_alignParentEnd="true"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/open_image_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:layout_marginEnd="21dp"
android:elevation="4dp"
android:src="@drawable/imageadd"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/save_image_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:elevation="4dp"
android:src="@drawable/imagesave"/>
</androidx.appcompat.widget.LinearLayoutCompat>
</RelativeLayout>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
Image Compression Activity Java Page
Open the Java page and get instances of the View components in the XML layout file.
The image file picker uses a library. Add the line below to your project build.gradle file.
implementation 'com.github.dhaval2404:imagepicker:2.1'
Copy and paste the code to the activity page.
public class CompressImageActivity extends AppCompatActivity {
private static final String TAG = CompressImageActivity.class.getSimpleName();
private ActivityCompressImageBinding binding;
private AppCompatTextView openImageDialog;
private AppCompatImageView selectedImageView;
private LinearLayoutCompat featureContainer;
private ThemedToggleButtonGroup themeGroup;
private AppCompatTextView selectedImageName, selectedImageSize;
private RadioGroup compressionGroup;
private AppCompatImageView saveImageBtn, openImageBtn;
private AppCompatEditText imageLengthValue, imageSizeValue;
private FileUtility fileUtility;
private int compressionStatus = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityCompressImageBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setTitle("Compress Image");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
selectedImageView = binding.selectedImage;
featureContainer = binding.featureContainer;
featureContainer.setVisibility(View.GONE);
selectedImageName = binding.selectedImageName;
selectedImageSize = binding.selectedImageSize;
imageLengthValue = binding.imageLengthValue;
imageSizeValue = binding.imageSizeValue;
themeGroup = binding.fileFormatOptions;
openImageDialog = binding.clickToUploadImage;
openImageDialog.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openGallery();
}
});
openImageBtn = binding.openImageBtn;
openImageBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openGallery();
}
});
compressionGroup = binding.compressionGroup;
compressionGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int checkedViewId) {
imageLengthValue.setVisibility(View.GONE);
imageSizeValue.setVisibility(View.GONE);
if(checkedViewId == R.id.without_compression){
compressionStatus = 1;
}
if(checkedViewId == R.id.auto_compression){
compressionStatus = 2;
}
if(checkedViewId == R.id.length_compression){
imageLengthValue.setVisibility(View.VISIBLE);
compressionStatus = 3;
}
if (checkedViewId == R.id.size_compression) {
imageSizeValue.setVisibility(View.VISIBLE);
compressionStatus = 4;
}
}
});
saveImageBtn = binding.saveImageBtn;
saveImageBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (compressionStatus == 0) {
Toast.makeText(CompressImageActivity.this, "Please select compression option", Toast.LENGTH_SHORT).show();
return;
}
if(compressionStatus == 1){
noCompression();
}
if(compressionStatus == 2){
autoCompression();
}
if(compressionStatus == 3){
String lengthValue = imageLengthValue.getText().toString();
if(lengthValue.isEmpty()){
Toast.makeText(CompressImageActivity.this, "Please enter image length", Toast.LENGTH_SHORT).show();
return;
}
int lengthVal = Integer.parseInt(lengthValue);
lengthCompression(lengthVal);
}
if (compressionStatus == 4) {
String sizeValue = imageSizeValue.getText().toString();
if(sizeValue.isEmpty()){
Toast.makeText(CompressImageActivity.this, "Please enter image size", Toast.LENGTH_SHORT).show();
return;
}
int sizeVal = Integer.parseInt(sizeValue);
File file = fileUtility.getUploadedFile();
compressBySize(sizeVal, file);
}
}
});
}
private String selectedImageExtension(){
String selectedExtension = "";
List<ThemedButton> buttons = themeGroup.getButtons();
for (ThemedButton button : buttons) {
if (button.isSelected()) {
selectedExtension = button.getSelectedText();
selectedExtension = selectedExtension.toLowerCase();
}
}
return selectedExtension;
}
private void noCompression(){
// isConvertedSupported
String userSelectedExt = selectedImageExtension();
//No conversion
StorageUtil storageUtil = new StorageUtil(this);
String resizePath = storageUtil.createInnerFolderStorage("Resize");
ResizeImageHelper helper = new ResizeImageHelper(this);
File reFile = helper.saveImageWithoutCompress(userSelectedExt, fileUtility.getFilenameWithoutExtension(), resizePath, fileUtility.getUploadedFile());
this.showCompressedResult(reFile);
}
private void autoCompression(){
// isConvertedSupported
String userSelectedExt = selectedImageExtension();
//No conversion
StorageUtil storageUtil = new StorageUtil(this);
String resizePath = storageUtil.createInnerFolderStorage("Resize");
int progressValue = 80;
ResizeImageHelper helper = new ResizeImageHelper(this);
File reFile = helper.resizeImageQuality(progressValue, userSelectedExt, fileUtility.getFilenameWithoutExtension(), resizePath, fileUtility.getUploadedFile());
this.showCompressedResult(reFile);
}
private void lengthCompression(int length){
String userSelectedExt = selectedImageExtension();
//No conversion
StorageUtil storageUtil = new StorageUtil(this);
String resizePath = storageUtil.createInnerFolderStorage("Resize");
ResizeImageHelper helper = new ResizeImageHelper(this);
File reFile = helper.resizeImageLength(length, userSelectedExt, fileUtility.getFilenameWithoutExtension(), resizePath, fileUtility.getUploadedFile());
this.showCompressedResult(reFile);
}
private void showCompressedResult(File file){
FileUtility newFileUtility = new FileUtility(file);
String resolution = newFileUtility.getFileResolution();
String fileSize = newFileUtility.getFileSize();
String fileExtension = newFileUtility.getExtension();
String absolutePath = newFileUtility.getFullPath();
Intent resultIntent = new Intent(this, CompressResultActivity.class);
resultIntent.putExtra(ConstantUtils.IMAGE_RESOLUTION, resolution);
resultIntent.putExtra(ConstantUtils.IMAGE_SIZE, fileSize);
resultIntent.putExtra(ConstantUtils.IMAGE_EXT, fileExtension);
resultIntent.putExtra(ConstantUtils.IMAGE_ABSOLUTE_PATH, absolutePath);
startActivity(resultIntent);
Bungee.slideLeft(this);
finish();
}
private void openGallery() {
ImagePicker.with(this)
.start();
}
private void toggleViews(){
openImageDialog.setVisibility(View.GONE);
featureContainer.setVisibility(View.VISIBLE);
}
private void setDefaultFileExtension(String ext) {
List<ThemedButton> buttons = themeGroup.getButtons();
buttons.forEach(themedButton -> {
if (themedButton.getText().equals(ext)) {
themeGroup.selectButton(themedButton.getId());
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
Uri uri = Objects.requireNonNull(data).getData();
File helperFile = FileHelper.getFileFromIntentUri(CompressImageActivity.this, data);
Picasso.get()
.load(helperFile)
.resize(400, 300)
.centerCrop()
.into(selectedImageView);
//Process file
fileUtility = new FileUtility(helperFile);
String ext = Files.getFileExtension(helperFile.getAbsolutePath());
//Show Image name and size
selectedImageName.setText(fileUtility.getFilename());
selectedImageSize.setText(fileUtility.getFileSize());
// Show Image extension
setDefaultFileExtension(fileUtility.getExtension().toUpperCase());
//Toggle Visibility
toggleViews();
} else if (resultCode == ImagePicker.RESULT_ERROR) {
Toast.makeText(CompressImageActivity.this, ImagePicker.getError(data), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(CompressImageActivity.this, "Task Cancelled", Toast.LENGTH_SHORT).show();
}
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int menuId = item.getItemId();
if(menuId == android.R.id.home){
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
@Override
public void onBackPressed() {
super.onBackPressed();
Bungee.slideRight(this);
}
private void compressBySize(int size, File file){
Luban.compress(CompressImageActivity.this, file)
.setMaxSize(size)
.putGear(Luban.CUSTOM_GEAR)
.asObservable()
.subscribe(new Consumer<File>() {
@Override
public void accept(File file) throws Exception {
//get compress file and save in another folder.
FileUtility fUtil = new FileUtility(file);
//Process size compression
processImageSizeCompression(fUtil);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.d(TAG, "Error compressing file size : " + throwable.getMessage());
}
});
}
private void processImageSizeCompression(FileUtility fUtil){
String filename = fUtil.getFilenameWithoutExtension();
String extension = fUtil.getExtension();
String size = fUtil.getFileSize();
System.out.println("Size Output : " + size);
StorageUtil storageUtil = new StorageUtil(this);
String destinationFolder = storageUtil.createInnerFolderStorage("Resize");
ResizeImageHelper helper = new ResizeImageHelper(this);
File resizeFiled = helper.resizeImageSize(extension, filename, destinationFolder, fUtil.getUploadedFile());
this.showCompressedResult(resizeFiled);
}
}
There are some helper classes we have created that will be used in upcoming tutorials. They will be covered as we move along with the tutorial.
In the upcoming tutorial, we will learn how to resize an image on Android.
All the topics in this Android project is accessible here.
If you have any questions or suggestions about this project, kindly use the comment box and get in touch.