DEV Community

Getinfo Toyou
Getinfo Toyou

Posted on

Building an Offline Image Compressor for Android: Solving the Slow Wi-Fi Problem

Have you ever been traveling, taking hundreds of photos, only to realize your phone's storage is almost full? Or maybe you're a developer or blogger trying to upload high-resolution images from a spotty hotel Wi-Fi connection? Relying on cloud storage or online compression tools isn't always practical when you're off the grid or dealing with limited bandwidth.

That specific scenario—needing to shrink images fast without relying on the internet—led me to build ImageSlim Free, an Android app designed to compress and resize photos directly on your device.

The Problem

Modern smartphones take high-quality photos, but those large sensors produce hefty file sizes. A single photo can easily be 5-10MB. If you need to share these images on a platform with strict file size limits, or if you're just trying to reclaim some local storage, you need a way to compress them.

While there are plenty of web-based tools, they require uploading your private photos to a server. This is slow, consumes mobile data, and raises privacy concerns. I wanted a fast, private, and completely offline solution.

The Tech Stack

To keep the app lightweight and performant, I stuck to the native Android ecosystem:

  • Language: Kotlin
  • UI: XML/View system
  • Image Processing: Native Android Bitmap APIs and BitmapFactory, supplemented by Kotlin Coroutines for asynchronous, non-blocking processing.
  • Storage: MediaStore APIs to securely read from and write to the user's gallery.

Technical Challenges

Building an image compressor sounds simple until you actually try to load multiple 10MB images into memory on a mobile device.

1. OutOfMemoryError (OOM)
This is a classic Android developer hurdle. Loading a full-resolution bitmap into memory can easily consume a large amount of RAM. If a user selects a batch of photos to compress, trying to hold them all in memory will crash the app instantly.

The Fix: Instead of loading the entire image at once, I utilized BitmapFactory.Options with inJustDecodeBounds = true to read the image dimensions first. Then, I calculated an appropriate inSampleSize to load a scaled-down version into memory before applying the final compression using Bitmap.compress().

2. Scoped Storage complexities
Managing file permissions has become much stricter in recent Android versions. Ensuring the app could efficiently read original photos and save the compressed versions back to the Pictures directory without constantly prompting the user required careful handling of the MediaStore API.

3. Balancing Quality and Size
Finding the sweet spot between file size reduction and acceptable visual quality took a lot of testing. ImageSlim Free allows users to reduce image file size by up to 90%. Implementing the logic to dynamically adjust the JPEG/WEBP quality parameters while resizing the dimensions was key to achieving this without noticeable artifacting.

Lessons Learned

Building ImageSlim Free reinforced the importance of memory profiling. Tools like the Android Studio Memory Profiler were invaluable in tracking down memory spikes and optimizing the image processing pipeline. I also learned that edge cases in Android's MediaStore are plentiful—different device manufacturers implement the gallery slightly differently, requiring robust error handling.

If you ever find yourself needing to shrink photos for a blog post, an email, or just to save space on your phone while traveling, it might be exactly what you need. It works completely offline.

You can try ImageSlim Free on Google Play or learn more at imageslim.getinfotoyou.com. Let me know what you think or if you have any questions about handling Bitmaps in Android!

Top comments (0)