Flutter&Firebase:上传图片前的压缩

问题描述 投票:12回答:6

我想将用户在我的应用中选择的照片发送到Firebase存储。我有一个简单的类,其属性为_imageFile,其设置如下:

File _imageFile;

_getImage() async {
    var fileName = await ImagePicker.pickImage();
    setState(() {
        _imageFile = fileName;
    });
}

之后,我发送照片与此代码:

final String rand1 = "${new Random().nextInt(10000)}";
final String rand2 = "${new Random().nextInt(10000)}";
final String rand3 = "${new Random().nextInt(10000)}";
final StorageReference ref = FirebaseStorage.instance.ref().child('${rand1}_${rand2}_${rand3}.jpg');
final StorageUploadTask uploadTask = ref.put(_imageFile);
final Uri downloadUrl = (await uploadTask.future).downloadUrl;
print(downloadUrl);

问题是照片通常非常大。在上传之前,Flutter / Dart中是否有任何压缩和调整照片大小的方法?我很好,质量下降。

firebase dart firebase-storage flutter
6个回答
7
投票

image_picker插件目前非常简单。可以直接添加用于指定所选图像的所需大小/质量的选项。如果您这样做,请发送拉货请求!


19
投票

2019年7月30日 - 更新

qazxsw poi插件现在支持qazxsw poi参数。你可以做点什么

image_picker

老答案

我遇到了这个并且能够用Dart imageQualityFile compressedImage = await ImagePicker.pickImage(source: ImageSource.camera, imageQuality: 85); 完成压缩/调整大小。你可以看看dart image packagepath provider的其他方式和更多的帮助。

这是我做的:

image api

然后我将examples上传到firebase存储。您可以使用quality属性调整jpg保存的质量,在我的情况下,我选择85(满分100)。

希望这可以帮助!如果您有任何疑问,请告诉我。


2
投票

以下代码是用于使用相机拍摄图像然后压缩它的代码:

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

你可以用这个来调用它:

compressedImage

2
投票

使用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 + '/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); } 插件并调用选择图像功能

import 'path/to/compress_image.dart' as CompressImage; // ... File file = await CompressImage.takeCompressedPicture(context);

将maxHeight和maxWidth更改为您需要的任何大小的图像。


1
投票

除了提到这个本地图书馆:image_picker

这是一个带有隔离的完全基于dart的压缩器,它可能使压缩与多核CPU中的UI线程并行。

您可能希望使用计算函数,这使得使用隔离器更简单:Future<File> imageFile = ImagePicker.pickImage(source: ImageSource.gallery , maxHeight: 200 , maxWidth: 200 ); https://pub.dartlang.org/packages/flutter_image_compress

https://docs.flutter.io/flutter/foundation/compute.html

https://flutter.io/cookbook/networking/background-parsing/

0
投票

我正在使用

包:图像/ image.dart

面对以下问题

  • 转换图像时显示空白页(压缩图像时可能需要这么多过程)
  • 压缩图像拉伸后看起来不太好

然后使用下面的插件,同样的工作正常没有任何问题,甚至更快,我所期望的

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

上述链接中可用的步骤和方法。

© www.soinside.com 2019 - 2024. All rights reserved.