Как объединить текст и файл изображения в один файл изображения во Flutter?

Ниже приведен фрагмент кода из функции, которая загружает сгенерированный QR-код (с использованием пакета qr_flutter) в хранилище Firebase; затем получает URL-адрес хранилища firebase для сохранения в пользовательской модели, которая загружается в firebase firestore (не показано).

Это работает нормально, однако я хочу загрузить файл, состоящий из QR-кода, ограниченного текстом заголовка выше и текстом адреса ниже. (По сути, столбец с дочерними элементами [название, qrFile, адрес]).

Мой вопрос: как мне объединить текст и мой qrFile в один файл изображения, который я могу загрузить в хранилище firebase?

String qrString = 'qr_data_here';
        final qrValidationResult = QrValidator.validate(
          data: qrString,
          version: QrVersions.auto,
          errorCorrectionLevel: QrErrorCorrectLevel.L,
        );
        if (qrValidationResult.status == QrValidationStatus.valid) {
          final qrCode = qrValidationResult.qrCode;
          const String title = 'title_name_here';
          final String address = 'address_here';
          final painter = QrPainter.withQr(
            qr: qrCode!,
            color: const Color(0xFF000000),
            gapless: true,
            embeddedImageStyle: null,
            embeddedImage: null,
          );
          Directory tempDir = await getTemporaryDirectory();
          String tempPath = tempDir.path;
          final ts = DateTime.now().millisecondsSinceEpoch.toString();
          String path = '$tempPath/$ts.png';
                                                // ui is from import 'dart:ui' as ui;
          final picData =
              await painter.toImageData(2048, format: ui.ImageByteFormat.png);
          // writeToFile is seen in code snippet below
          await writeToFile(
            picData!,
            path,
          );
        } else {
          genericErrorDialog(context);
        }
        // qrStorage is a reference to a folder in firebase storage
        await qrStorage.child('name_here').putFile(qrFile);
        var url =
            await qrStorage.child('name_here').getDownloadURL();
  late File qrFile;

  Future<void> writeToFile(ByteData data, String path) async {
    final buffer = data.buffer;
    qrFile = await File(path).writeAsBytes(
        buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
  }
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
43
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Одним из решений является использование пакета снимков экрана (https://pub.dev/packages/скриншот). Этот пакет имеет функцию сохранения виджета в виде изображения (без его отображения на экране), как показано ниже.

ScreenshotController screenshotController = ScreenshotController();


await screenshotController
              .captureFromWidget(CustomWidget())
              .then((capturedImage) async {
            await do_something_with_capturedImage_here();
          });

Поскольку это относится к моему вопросу конкретно; Ниже приведен код для создания кода qr, размещения его в виджете (требуется дополнительное форматирование) с текстом, а затем сохранения виджета в виде файла изображения и загрузки в firebase.

String qrString = 'qr_data_here';
        final qrValidationResult = QrValidator.validate(
          data: qrString,
          version: QrVersions.auto,
          errorCorrectionLevel: QrErrorCorrectLevel.L,
        );
        if (qrValidationResult.status == QrValidationStatus.valid) {
          final qrCode = qrValidationResult.qrCode;
          const String title = 'title_name_here';
          final String address = 'address_here';
          final painter = QrPainter.withQr(
            qr: qrCode!,
            color: const Color(0xFF000000),
            gapless: true,
            embeddedImageStyle: null,
            embeddedImage: null,
          );
          Directory tempDir = await getTemporaryDirectory();
          String tempPath = tempDir.path;
          final ts = DateTime.now().millisecondsSinceEpoch.toString();
          String path = '$tempPath/$ts.png';
                                                // ui is from import 'dart:ui' as ui;
          final picData =
              await painter.toImageData(2048, format: ui.ImageByteFormat.png);
          // writeToFile is seen in code snippet below
          await writeToFile(
            picData!,
            path,
          );
          await screenshotController
              .captureFromWidget(Column(
            children: [
              Text(title),
              Image.file(qrFile),
              Text(address),
            ],
          ))
              .then((capturedImage) async {
            await widgetToImageFile(capturedImage);
          });
        } else {
          genericErrorDialog(context);
        }
        // qrStorage is a reference to a folder in firebase storage
        await qrStorage.child('name_here').putFile(fullQrFile);
        var url =
            await qrStorage.child('name_here').getDownloadURL();
ScreenshotController screenshotController = ScreenshotController();
  late File qrFile;
  late File fullQrFile;


  Future<void> writeToFile(ByteData data, String path) async {
    final buffer = data.buffer;
    qrFile = await File(path).writeAsBytes(
        buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
  }

  Future<void> widgetToImageFile(
    Uint8List capturedImage,
  ) async {
    Directory newTempDir = await getTemporaryDirectory();
    String newTempPath = newTempDir.path;
    final newTs = DateTime.now().millisecondsSinceEpoch.toString();
    String path = '$newTempPath/$newTs.png';
    fullQrFile = await File(path).writeAsBytes(capturedImage);
  }

Другие вопросы по теме