Я пытался сжать изображение перед отправкой на сервер. Но изображения формата HEIC невозможно сжать с помощью пакета (flutter_image_compress). Также я не нашел пакета, который может конвертировать изображения для Flutter Web. Какие еще варианты есть?
Я пытался найти способ сделать это без использования сторонних пакетов, но не смог его найти.
Нет, здесь перечислены только платформы Android и iOS. Насколько я знаю, веб не поддерживается.
«Я пытался сжать изображение перед отправкой его на сервер» — HEIC уже представляет собой сжатое изображение, намного лучше, чем JPEG (в большинстве случаев оно может занимать всего половину места, которое занимал бы файл JPEG)
В Flutter Web до сих пор нет прямого способа сделать это. Вы можете сделать это, реализовав javascript в index.html, или использовать логику на стороне сервера для преобразования heic в формат jpeg.
Поскольку у Flutter Web нет прямого способа конвертировать фотографии, я использовал пакет «heic2any» для JavaScript.
Обновить файл index.html (./web/index.html).
<!-- HEIC to any converter -->
<script src = "https://unpkg.com/heic2any"></script>
<script>
async function convertHeicToJpeg(heicFile) {
try {
const convertedBlob = await heic2any({
blob: heicFile,
toType: "image/jpeg",
});
return convertedBlob;
} catch (error) {
console.error("HEIC to JPEG conversion failed:", error);
throw error;
}
}
</script>
Мой код HeicToJpegService:
import 'dart:async';
import 'dart:html'; // for using Blob
import 'dart:js_util' as js_util;
import 'dart:typed_data';
import 'package:js/js.dart';
@JS('convertHeicToJpeg')
external Future<Blob> convertHeicToJpegBlob(Blob heicFile);
class HeicToJpegService {
/// Convert Blob to Uint8List
Future<Uint8List> _blobToUint8List(Blob blob) async {
final completer = Completer<Uint8List>();
final reader = FileReader();
reader.readAsArrayBuffer(blob);
reader.onLoadEnd.listen((event) {
completer.complete(Uint8List.fromList(reader.result as List<int>));
});
reader.onError.listen((event) {
completer.completeError(reader.error ?? 'Unknown error');
});
return completer.future;
}
Future<Uint8List> convertHeicToJpeg(Uint8List fileBytes) async {
final blob = Blob([fileBytes]);
final convertedBlob = await js_util.promiseToFuture<Blob>(
js_util.callMethod(window, 'convertHeicToJpeg', [blob]),
);
return await _blobToUint8List(convertedBlob);
}
}
Этот код работает так, как ожидалось. С этим тоже проблем нет.
Вы пробовали heif_converter?