captureFinalScreenshot method

Future<Uint8List?> captureFinalScreenshot({
  1. required ImageInfos imageInfos,
  2. required ThreadCaptureState? backgroundScreenshot,
  3. Widget? widget,
  4. BuildContext? context,
  5. Uint8List? originalImageBytes,
  6. Size? targetSize,
})

Captures the final screenshot based on the provided parameters.

This method handles the screenshot capture process, either by using an existing background screenshot, creating a new screenshot, or validating an existing image's format and size. It ensures the screenshot meets the required format and size, and handles errors by attempting a new capture.

  • Parameters:

    • imageInfos: Information about the image being captured.
    • backgroundScreenshot: An optional existing screenshot to use.
    • widget: An optional widget to capture a screenshot from.
    • context: The build context for the widget.
    • originalImageBytes: Optional bytes of the original image.
  • Returns: The captured screenshot as a Uint8List?.

Implementation

Future<Uint8List?> captureFinalScreenshot({
  required ImageInfos imageInfos,
  required ThreadCaptureState? backgroundScreenshot,
  Widget? widget,
  BuildContext? context,
  Uint8List? originalImageBytes,
  Size? targetSize,
}) async {
  Uint8List? bytes;

  bool activeScreenshotGeneration =
      backgroundScreenshot != null && !backgroundScreenshot.broken;
  String id = activeScreenshotGeneration
      ? backgroundScreenshot.id
      : generateUniqueId();

  try {
    if (!kIsWeb) {
      _isolateManager.destroyAllActiveTasks(id);
    } else {
      _webWorkerManager.destroyAllActiveTasks(id);
    }

    if (originalImageBytes == null) {
      if (activeScreenshotGeneration) {
        // Get screenshot from isolated generated thread.
        bytes = await backgroundScreenshot.completer.future;
      } else {
        // Capture a new screenshot if the current screenshot is broken or
        // didn't exists.
        bytes = widget == null
            ? await _capture(
                id: id,
                imageInfos: imageInfos,
              )
            : await captureFromWidget(
                widget,
                id: id,
                targetSize: targetSize,
                imageInfos: imageInfos,
              );
      }
    } else {
      // If the user didn't change anything just ensure the outputformat
      // is correct.
      bytes = originalImageBytes;

      String contentType = lookupMimeType('', headerBytes: bytes) ?? 'Unkown';
      List<String> sp = contentType.split('/');
      bool formatIsCorrect = sp.length > 1 &&
          (_configs.imageGenerationConfigs.outputFormat.name == sp[1] ||
              (sp[1] == 'jpeg' &&
                  _configs.imageGenerationConfigs.outputFormat ==
                      OutputFormat.jpg));

      double outputRatio = imageInfos.pixelRatio;
      if (!_configs.imageGenerationConfigs.captureOnlyDrawingBounds &&
          context != null &&
          context.mounted) {
        outputRatio = max(
            imageInfos.pixelRatio, MediaQuery.of(context).devicePixelRatio);
      }
      bool isOutputSizeTooLarge = _isOutputSizeTooLarge(
        imageInfos.renderedSize,
        outputRatio,
        generateOnlyThumbnail,
      );
      if (!formatIsCorrect || isOutputSizeTooLarge) {
        final ui.Image image = await decodeImageFromList(originalImageBytes);
        if (_configs.imageGenerationConfigs.generateInsideSeparateThread) {
          if (kIsWeb || isOutputSizeTooLarge) {
            /// currently in the web flutter decode the image wrong so we need
            /// to recapture it.
            /// bytes = await _webWorkerManager.send(
            ///   await _generateSendEncodeData(
            ///     id: id,
            ///     image: image,
            ///   ),
            /// );
            bytes = widget == null
                ? await _capture(
                    id: id,
                    imageInfos: imageInfos,
                  )
                : await captureFromWidget(
                    widget,
                    id: id,
                    targetSize: targetSize,
                    imageInfos: imageInfos,
                  );
          } else {
            bytes = await _isolateManager.send(
              await _generateSendEncodeData(
                id: id,
                image: image,
              ),
            );
          }
        } else {
          bytes = await _encodeImage(image);
        }
      }
    }
  } catch (e) {
    debugPrint(e.toString());

    // Take a new screenshot when something went wrong.
    bytes = widget == null
        ? await _capture(
            id: id,
            imageInfos: imageInfos,
          )
        : await captureFromWidget(
            widget,
            id: id,
            targetSize: targetSize,
            imageInfos: imageInfos,
          );
  }
  return bytes;
}