dart - Flutter & Firebase: Compression before upload image

ID : 131345

viewed : 3

Tags : firebasedartfirebase-storageflutterfirebase

Top 5 Answer for dart - Flutter & Firebase: Compression before upload image

vote vote

95

June 05, 2020 - Update

The image_picker plugin now supports an imageQuality paramater. You can do something like

ImagePicker imagePicker = ImagePicker(); PickedFile compressedImage = await imagePicker.getImage(   source: ImageSource.camera,   imageQuality: 85, ); 

Old Answer

or if you want to compress an image without using ImagePicker

I ran into this and was able to accomplish compression / resizing with the Dart image package along with path provider. You can look at dart image api and examples for other ways and more help.

Here's what I did:

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)); } 

Then I uploaded compressedImage to firebase storage. You can adjust the quality that the jpg is saved with using the quality property, in my case I chose 85 (out of 100).

Hope this helps! Let me know if you have any questions.

vote vote

84

The image_picker plugin is currently very simple. It would be straightforward to add an option for specifying the desired size/quality of the picked image. If you do this, please send us a pull request!

vote vote

70

Use image_picker plugin and call pick image function as

Future<File> imageFile = ImagePicker.pickImage(source: ImageSource.gallery , maxHeight: 200 , maxWidth: 200 );

change maxHeight and maxWidth to whatever size of image you need.

vote vote

61

There are many solutions :

Use image_picker package:

You can use the built-in imageQuality property of ImagePicker to compress the image. This property takes a value between 0 and 100 and represents a percentage of the quality of the original image.

First, add image_picker as a dependency in your pubspec.yaml file.

Usage

  File _image;    Future getImage() async {     var image = await ImagePicker.pickImage(         source: ImageSource.gallery,                   imageQuality: 25,     );      setState(() {       _image = image;     });   } 

The advantage of this approach is that it is embedded in the image_picker package and is therefore incredibly easy to use.

You can also adjust the quality from the Image widget.

Use filterQuality to set the FilterQuality of the image.

Example :

Image.asset('assets/kab1.png', filterQuality: FilterQuality.high,),  

These properties are present in AssetImage , NetworkImage , FileImage and MemoryImage.

You can also simply resize the image (Resizing an image can compress it). To do so, try the ResizeImage widget

Another solution is to use flutter_image_compress package

vote vote

51

Besides mentioning this native library: https://pub.dartlang.org/packages/flutter_image_compress

This is a fully dart based compressor with isolates, which might make the compression parallel to UI thread in multi core CPUs.

You might want to use compute function which makes using isolates simpler: https://docs.flutter.io/flutter/foundation/compute.html https://flutter.io/cookbook/networking/background-parsing/

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); } 

Top 3 video Explaining dart - Flutter & Firebase: Compression before upload image

Related QUESTION?