How to Compress Image Before Uploading to Firebase and Flutter?
If you’re a Flutter developer working on an app that involves image uploads to Firebase, you might have encountered the challenge of dealing with large image file sizes. Uploading high-resolution images directly to Firebase can consume valuable bandwidth and storage, leading to slower uploads and increased costs.
Earlier we have been through Step By Step Guide to How to Integrate Firebase in Flutter Mobile Application Where users will follow certain steps. Sometimes the user needs to store images into Firebase and It may also happen that it has a large amount of data so in this article we will go through How to Compress Image Before Uploading to Firebase and Flutter?
Compress Image Before Uploading to Firebase and Flutter
In this case, we have considered that the user has made use of the image_picker plugin for the same. The image_picker plugin now supports an imageQuality parameter. Code Snippet will look like below:
ImagePicker imagePicker = ImagePicker(); PickedFile compressedImage = await imagePicker.getImage( source: ImageSource.camera, imageQuality: 85, );
Compress an image without using the ImagePicker plugin
import 'package:image/image.dart' as Im; import 'package:path_provider/path_provider.dart'; import 'dart:math' as Math; void compressImage() async { File imageFile = await ImagePicker.pickImage(); final tempDir = await getTemporaryDirectory(); final path = tempDir.path; int rand = new Math.Random().nextInt(10000); Im.Image image = Im.decodeImage(imageFile.readAsBytesSync()); Im.Image smallerImage = Im.copyResize(image, 500); // choose the size here, it will maintain aspect ratio var compressedImage = new File('$path/img_$rand.jpg')..writeAsBytesSync(Im.encodeJpg(image, quality: 85)); }
Users can also set maxHeight,maxWidth. Consider a code snippet like the below:
Future<File> imageFile = ImagePicker.pickImage(source: ImageSource.gallery , maxHeight: 200 , maxWidth: 200 );
This is a fully dart based compressor with isolates, which might make the compression parallel to UI thread in multi-core CPUs. Consider a code snippet like the below:
import 'package:image/image.dart' as ImageLib; import 'package:path_provider/path_provider.dart'; Future<void> getCompressedImage(SendPort sendPort) async { ReceivePort receivePort = ReceivePort(); sendPort.send(receivePort.sendPort); List msg = (await receivePort.first) as List; String srcPath = msg[0]; String name = msg[1]; String destDirPath = msg[2]; SendPort replyPort = msg[3]; ImageLib.Image image = ImageLib.decodeImage(await new File(srcPath).readAsBytes()); if (image.width > 500 || image.height > 500) { image = ImageLib.copyResize(image, 500); } File destFile = new File(destDirPath + '/' + name); await destFile.writeAsBytes(ImageLib.encodeJpg(image, quality: 60)); replyPort.send(destFile.path); } Future<File> compressImage(File f) async { ReceivePort receivePort = ReceivePort(); await Isolate.spawn(getCompressedImage, receivePort.sendPort); SendPort sendPort = await receivePort.first; ReceivePort receivePort2 = ReceivePort(); sendPort.send([ f.path, f.uri.pathSegments.last, (await getTemporaryDirectory()).path, receivePort2.sendPort, ]); var msg = await receivePort2.first; return new File(msg); }
if (false == await SimplePermissions.checkPermission( Permission.ReadExternalStorage)) { await SimplePermissions.requestPermission( Permission.ReadExternalStorage); } File img = await ImagePicker.pickImage( source: ImageSource.gallery); if (null != img) { img = await compressImage(img); }
Consider a custom function like the below:
import 'dart:async' show Future; import 'dart:io' show File; import 'package:flutter/foundation.dart' show compute; import 'package:flutter/material.dart' show BuildContext; import 'package:image/image.dart' as Im; import 'dart:math' as Math; import 'package:image_picker/image_picker.dart'; import 'package:path_provider/path_provider.dart' show getTemporaryDirectory; Future<File> takeCompressedPicture(BuildContext context) async { var _imageFile = await ImagePicker.pickImage(source: ImageSource.camera); if (_imageFile == null) { return null; } // You can have a loading dialog here but don't forget to pop before return file; final tempDir = await getTemporaryDirectory(); final rand = Math.Random().nextInt(10000); _CompressObject compressObject = _CompressObject(_imageFile, tempDir.path, rand); String filePath = await _compressImage(compressObject); print('new path: ' + filePath); File file = File(filePath); // Pop loading return file; } Future<String> _compressImage(_CompressObject object) async { return compute(_decodeImage, object); } String _decodeImage(_CompressObject object) { Im.Image image = Im.decodeImage(object.imageFile.readAsBytesSync()); Im.Image smallerImage = Im.copyResize( image, 1024); // choose the size here, it will maintain aspect ratio var decodedImageFile = File(object.path + 'https://d1own1in5yzwrz.cloudfront.net/img_${object.rand}.jpg'); decodedImageFile.writeAsBytesSync(Im.encodeJpg(smallerImage, quality: 85)); return decodedImageFile.path; } class _CompressObject { File imageFile; String path; int rand; _CompressObject(this.imageFile, this.path, this.rand); }
You can call this very easy with this:
import 'path/to/compress_image.dart' as CompressImage; // ... File file = await CompressImage.takeCompressedPicture(context);
Conclusion:
In this article, We have been through How to Compress Image Before Uploading to Firebase and Flutter?
Keep Learning !!! Keep Fluttering !!!
Still, need a Support for Flutter Development? Do let us know.
FlutterAgency.com is our portal Platform dedicated to Flutter Technology and Flutter Developers. The portal is full of cool resources from Flutter like Flutter Widget Guide, Flutter Projects, Code libs and etc.
FlutterAgency.com is one of the most popular online portal dedicated to Flutter Technology and daily thousands of unique visitors come to this portal to enhance their knowledge on Flutter.
Contemporary ventures
Recent blog
ready to get started?
Fill out the form below and we will be in touch soon!
"*" indicates required fields