DEV Community

Cover image for Flutter Image Compression: Ensuring High Quality

Flutter Image Compression: Ensuring High Quality

In today's digital age, we often find ourselves taking countless photos and capturing memories on our devices. As developers, we want to make sure these images are not just beautiful but also efficient when it comes to uploading them to a server. This is where image compression comes into play.

In this article, we’ll explore the ins and outs of image compression for Flutter, focusing specifically on how to balance quality and performance for seamless uploads. Whether you're building a social media app or a photo-sharing platform, understanding the art of compression can greatly enhance user experience while keeping your application running smoothly. Let's dive in!


Image compression is the process of reducing the file size of an image without significantly compromising its quality. It involves removing unnecessary data or utilizing algorithms to make the file smaller. This is essential for several reasons, especially when uploading images to a server.

Firstly, larger image sizes can lead to longer upload times. For users with slower internet connections or limited bandwidth, this delay can result in frustration and a poor overall experience. By compressing images before uploading, developers can ensure faster transfer speeds, making the process more seamless for users.

Secondly, uploading large images can strain server resources. This can lead to increased storage costs and slower response times for other users accessing the server. By utilizing image compression, developers not only enhance the user experience but also optimize server performance and efficiency.

So, understanding and implementing image compression is vital for any Flutter developer looking to improve their app's performance and user satisfaction, particularly in scenarios where image uploads are a common requirement.

Types of Image Conversion

When it comes to image compression, there are two main types: lossy compression and lossless compression. Each has its pros and cons, making them suitable for different situations.

Lossy Compression

Source: https://news.txst.edu/research-and-innovation/2021/txst-researchers-to-explore-state-of-the-art-lossy-compression.htmlImage Source

What it is: Lossy compression reduces image size by permanently removing some of the image’s data. It focuses on discarding details that are less noticeable to the human eye, making the file significantly smaller.

Impact on Quality: This approach often leads to a small reduction in image quality, which may or may not be visible depending on the level of compression used. Higher compression ratios (smaller file sizes) often result in more noticeable quality loss, like blurring or pixelation.

Best Use Cases: Ideal for photos or images with lots of colors and gradients, like user-uploaded images or social media photos. JPEG is a common format that uses lossy compression.

Lossless Compression

Source: https://cyberhoot.com/cybrary/lossless-compression/Image Source

What it is: Lossless compression reduces file size without removing any image data. It achieves smaller files by finding and compressing patterns within the image, but no data is lost, so you can fully restore the original image.

Impact on Quality: Since no data is discarded, image quality remains intact. However, lossless compression doesn’t reduce file size as dramatically as lossy compression, especially for complex images.

Best Use Cases: Suitable for graphics, icons, or images where high fidelity is crucial, like logos or text-heavy images. PNG and GIF formats often use lossless compression.

Choosing Between Lossy and Lossless

When Quality is Crucial: Use lossless compression to retain full detail, especially if users may zoom in or if the image contains text or important details.

When Reducing File Size is Key: Use lossy compression when you need a smaller file size and can afford slight quality loss, especially for thumbnails or images in feed views where high resolution isn't necessary.

In summary, the choice between lossy and lossless compression hinges on your specific needs: prioritize speed and smaller files with lossy compression, or opt for higher quality with lossless compression. Understanding these options will help you optimize image uploads in your Flutter app.


In this article, we'll focus more on lossy compression to achieve slight quality loss and smaller file sizes.

Original (974Kb)

Image descriptionImage Source
I have this original size file with 974Kb file size.

And then i do compression with 90% Quality.

90% Quality (318Kb)

Image descriptionWith 90% quality we can achieve the compression rate at approximately 67.35% from 974Kb to 318Kb.

50% Quality (109Kb)

Image descriptionWith 50% quality we can achieve the compression rate at approximately 88.81% from 974Kb to 109Kb.

10% Quality (55Kb)

Image descriptionWith 10% quality we can achieve the compression rate at approximately 94.35% from 974Kb to 55Kb.


Image descriptionBased on the quality comparisons above, you can decide which compression level works best for your needs. If image quality is a priority (for product photos or detailed images), higher quality settings (e.g., 90 or above) should be used to maintain clarity, though they result in larger file sizes.

If file size is more important, such as for thumbnails or gallery images, lower quality settings (e.g., 50 or even 10) can be used to significantly reduce file size, though some visual degradation will occur. The choice depends on whether you prioritize visual fidelity or performance and size optimization.


Code Implementation

Here’s an example of a function to compress an image in Flutter using the flutter_image_compress package:

You only need these two packages:
Flutter Image Compress Package
Flutter Image Picker

Pick Image

import 'package:image_picker/image_picker.dart';

final ImagePicker picker = ImagePicker();
File? selectedImage;

Future<void> pickImage() async {
    final pickedFile = await picker.pickImage(source: ImageSource.gallery);
    if (pickedFile != null) {
      setState(() {
        selectedImage = File(pickedFile.path);
      });
    }
  }
Enter fullscreen mode Exit fullscreen mode

Compress Image

import 'package:path/path.dart' as path;
import 'package:flutter_image_compress/flutter_image_compress.dart';

Future<XFile> compressImageFile(
    {
      required File imageFile, 
      int quality = 80, 
      CompressFormat format = CompressFormat.jpeg
    }) async {

    DateTime time = DateTime.now();
    final String targetPath = path.join(
      Directory.systemTemp.path, 'imagetemp-${format.name}-$quality-${time.second}.${format.name}'
    );

    final XFile? compressedImageFile = await FlutterImageCompress.compressAndGetFile(
      imageFile.path,
      targetPath,
      quality: quality,
      format: format
    );

    if (compressedImageFile == null){
      throw ("Image compression failed! Please try again.");
    }
    debugPrint("Compressed image saved to: ${compressedImageFile.path}");
    return compressedImageFile;
  }
Enter fullscreen mode Exit fullscreen mode

UI Example

Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
    if (selectedImage != null) 
      Image.file(
        selectedImage!
      ),
    TextButton(
      onPressed: () async {
        await pickImage();
      }, 
      child: const Text("Pick Image")
    ),

    ElevatedButton(
      onPressed: () {
        if (selectedImage != null) {
          compressImageFile(
            imageFile: selectedImage!,
            quality: 10
          );
        }
      }, 
      child: const Text("Compress")
    )
  ],
)
Enter fullscreen mode Exit fullscreen mode

If you'd like to view the code for the sample usage app above, please visit:
Github

References:
www.dhiwise.com
www.adobe.com
cyberhoot.com

Top comments (0)