web-dev-qa-db-ja.com

Flutter&Firebase:画像をアップロードする前の圧縮

アプリでユーザーが選択した写真をFirebase Storageに送信したい。次のように設定されたプロパティ_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にアップロード前に写真を圧縮およびサイズ変更する方法はありますか?品質の低下は問題ありません。

16

image_picker プラグインは現在非常にシンプルです。選択した画像の目的のサイズ/品質を指定するオプションを追加するのは簡単です。これを行う場合は、プルリクエストを送信してください。

8
Collin Jackson

2019年7月30日-更新

image_picker プラグインはimageQualityパラメータをサポートするようになりました。次のようなことができます

File compressedImage = await ImagePicker.pickImage(source: ImageSource.camera, imageQuality: 85);

古い回答

私はこれに遭遇し、Dart image packagepath provider で圧縮/サイズ変更を達成することができました。他の方法やその他のヘルプについては、Dart image api および examples をご覧ください。

私がやったことは次のとおりです。

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をfirebaseストレージにアップロードしました。 jpgが保存される品質は、qualityプロパティを使用して調整できます。私の場合、85(100のうち)を選択しました。

お役に立てれば!ご質問がある場合はお知らせください。

23
Mans

image_picker プラグインを使用して、画像の選択関数を次のように呼び出します。

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

maxHeightとmaxWidthを必要な画像のサイズに変更します。

2
charan ghumman

次のコードは、カメラで画像を撮影して圧縮するために使用するものです。

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);
2
Robert Brunhage

このnativeライブラリに言及する以外に: https://pub.dartlang.org/packages/flutter_image_compress

これは完全にDartベースのisolatesを備えたコンプレッサーであり、マルチコアCPUのUIスレッドに圧縮を並行させる可能性があります。

分離の使用をより簡単にする計算関数を使用することもできます。 https://docs.flutter.io/flutter/foundation/compute.htmlhttps://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);
}
2
zero.zero.seven

私が使用している間

パッケージ:image/image.Dart

以下の問題に直面している

  • 画像の変換中に空白ページを表示します(画像の圧縮中に非常に多くのプロセスを要する場合があります)
  • 圧縮画像が引き伸ばされ、見た目が良くなくなった後

次に、以下のプラグインを使用し、同じ問題なく問題なく動作し、さらに速く、私が期待したもの

https://github.com/btastic/flutter_native_image.git

上記のリンクで利用可能な手順と方法。

0
Anand saga