programing

Float & Firebase:이미지 업로드 전 압축

testmans 2023. 6. 29. 19:54
반응형

Float & 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);

문제는 사진들이 종종 매우 크다는 것입니다.업로드하기 전에 사진을 압축하고 크기를 조정하는 방법이 Float/Dart에 있습니까?저는 품질이 떨어져도 괜찮습니다.

2020년 6월 5일 - 업데이트

이제 image_picker 플러그인이 다음을 지원합니다.imageQuality매개 변수당신은 다음과 같은 것을 할 수 있습니다.

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

오래된 대답

또는 사용하지 않고 이미지를 압축하려는 경우ImagePicker

문제를 우연히 만나 경로 공급자와 함께 Dart 이미지 패키지를 사용하여 압축/크기 조정을 수행할 수 있었습니다.다트 이미지 api 예제에서 다른 방법과 더 많은 도움말을 볼 수 있습니다.

제가 한 일은 다음과 같습니다.

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화재 기지 저장소로.품질 속성을 사용하여 jpg가 저장되는 품질을 조정할 수 있습니다. 저의 경우 85개(100개 중)를 선택했습니다.

이것이 도움이 되길 바랍니다!질문이 있으면 저에게 알려주세요.

image_picker 플러그인은 현재 매우 단순합니다.선택한 이미지의 원하는 크기/품질을 지정하는 옵션을 추가하는 것은 간단합니다.만약 당신이 이것을 한다면, 우리에게 풀 요청을 보내주세요!

다양한 솔루션이 있습니다.

image_picker 패키지 사용:

기본 제공 기능을 사용할 수 있습니다.imageQuality이미지를 압축할 ImagePicker의 속성입니다.이 속성은 다음 사이의 값을 사용합니다.0그리고.100원본 이미지 품질의 백분율을 나타냅니다.

저먼추를 합니다.image_pickerdubspec.dubspec의 됩니다.

사용.

  File _image;

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

    setState(() {
      _image = image;
    });
  }

이 접근 방식의 장점은 image_picker 패키지에 포함되어 있기 때문에 사용하기가 매우 쉽다는 것입니다.

이미지 위젯에서 품질을 조정할 수도 있습니다.

사용하다filterQuality설정하기 위해FilterQuality이미지의

예:

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

은 이한속다있습다니음에 .AssetImage,NetworkImage,FileImage그리고.MemoryImage.

또한 단순히 이미지 크기를 조정할 수도 있습니다(이미지 크기를 조정하면 압축할 수 있음).이미지 크기 조정 위젯을 사용해 보십시오.

또 다른 솔루션은 flot_image_compress 패키지를 사용하는 것입니다.

image_picker 플러그인을 사용하고 다음과 같이 이미지 선택 함수를 호출합니다.

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

maxHeight 및 maxWidth를 원하는 크기의 이미지로 변경합니다.

네이티브 라이브러리를 언급하는 것 외에: https://pub.dartlang.org/packages/flutter_image_compress

압축은 아이솔레이트가 있는 완전한 다트 기반 압축기로, 멀티 코어 CPU의 UI 스레드와 병렬로 압축할 수 있습니다.

분리막을 더 쉽게 사용할 수 있는 계산 기능을 사용할 수 있습니다. 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);
}

다음 코드는 카메라로 이미지를 찍은 다음 압축할 때 사용하는 코드입니다.

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

사용 중

패키지:image/image.syslog

아래의 문제들에 직면한

  • 이미지를 변환하는 동안 빈 페이지 표시(이미지를 압축하는 동안 너무 많은 프로세스가 필요할 수 있음)
  • 압축 이미지가 늘어지고 보기가 좋지 않은 후

그런 다음 플러그인 아래에서 사용되며, 동일한 것이 문제 없이 잘 작동하고, 훨씬 더 빠르고 내가 기대한 것입니다.

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

단계 및 방법은 위 링크에서 사용할 수 있습니다.

flot_image_compress라는 플러그인을 사용할 수 있습니다.

// Active image file
File _imageFile;

// Select an image via gallery or camera
Future<void> _pickImage(ImageSource source) async {
  File selected = await ImagePicker.pickImage(source: source);

// Compress plugin
  File compressedImage = await FlutterImageCompress.compressAndGetFile(
    selected.path,
    selected.path,
    quality: 50,
  );

  setState(() {
    _imageFile = compressedImage;
    print('compressedimagesize: ${_imageFile.lengthSync()}');
  });
}

Voila! 압축 파일 이미지

Firebase를 사용하고 있으므로 [확장] - [이미지 크기 조정]을 사용할 수 있습니다.원본 이미지를 유지하거나 삭제할 수 있는 옵션을 제공하며 설치 및 사용이 매우 쉽습니다.

다음과 같이 할 수 있습니다.

//Compressing Image
    File compressedImg = await FlutterNativeImage.compressImage(
      _image.path,
      quality: 70,
    );
//Compressing Image

음.
모바일에 있다면 사용할 수 있습니다. flutter_image_compress: ^1.0.0그 일을 할 것입니다.

예: eUint8List 및 품질을 전달하면 압축 이미지를 즉시 얻을 수 있습니다.

Future<Uint8List> testComporessList(Uint8List uint8List) async {
    var result = await FlutterImageCompress.compressWithList(
      uint8List,
      quality: 50,
    );
    return result;
}

하지만 만약 당신이 float 웹에 있다면, 당신은 이미지 선택기 등 외에 다른 옵션을 얻을 수 없을 것입니다.
저는 결국 자바스크립트를 사용하게 됩니다.여기서 답을 찾을 수 있습니다.
Floating Web: 이미지/파일을 압축하는 방법

업데이트 2020 'pickImage'는 더 이상 사용되지 않으며 사용해서는 안 됩니다. 대신 imagePicker.getImage() 메서드를 사용합니다**

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

이미지 품질 문서:

선택한 이미지를 싸고 있는 PickedFile 개체를 반환합니다.반환된 PickedFile은 단일 APP 세션 내에서 사용됩니다.파일 경로를 저장하지 않고 세션 간에 사용합니다.source 인수는 이미지의 출처를 제어합니다.ImageSource.camera 또는 ImageSource.gallery일 수 있습니다.iOS는 HEIC 이미지를 지원하는 반면, Android 8 이하는 지원하지 않습니다.Android 9 이상은 크기 수정과 함께 사용하는 경우 HEIC 이미지만 지원하며, 그 사용법은 아래에 설명되어 있습니다.지정할 경우 이미지는 최대 maxWidth width 및 maxHit 높이가 됩니다.그렇지 않으면 이미지가 원래 너비와 높이로 반환됩니다.imageQuality 인수는 0-100 범위에서 이미지의 품질을 수정합니다. 여기서 100은 원본/최대 품질입니다.imageQuality가 null이면 원래 품질의 영상이 반환됩니다.압축은 JPEG와 Android PNG 및 WebP와 같은 특정 이미지 유형에만 지원됩니다.선택한 이미지에 대해 압축이 지원되지 않으면 경고 메시지가 기록됩니다.기본 설정 카메라 장치를 사용하여 소스가 ImageSource.camera일 때 사용할 카메라를 지정합니다.소스가 ImageSource.gallery인 경우 기본 CameraDevice는 무시됩니다.선택한 카메라가 장치에서 지원되지 않는 경우에도 무시됩니다.기본값은 CameraDevice.rear입니다.Android에는 전면 또는 후면 카메라를 열어야 하는지 여부를 지정하기 위한 문서화된 매개 변수가 없으며, 이 기능은 Android 장치에서 작동하지 않습니다.Android에서는 다양한 이유로 Main Activity가 파괴될 수 있습니다.그렇게 되면 이 통화에서 결과가 손실됩니다.그런 다음 앱이 다시 실행되어 손실된 데이터를 검색할 때 getLostData를 호출할 수 있습니다.

언급URL : https://stackoverflow.com/questions/46515679/flutter-firebase-compression-before-upload-image

반응형