encodeImageToDataURL function IO

Future<String?> encodeImageToDataURL(
  1. Images images, [
  2. int frame = 0
])

Encodes a specific frame from an Images list into a base64 Data URL string (PNG format).

This function waits for the image data to be loaded if necessary before proceeding with the encoding.

  • images: The Images list containing the image frames. This list should not be empty and the specified frame index must be valid.
  • frame: The index of the image frame within the images list to encode. Defaults to 0 (the first frame).

Returns a Future that completes with a String? representing the base64 encoded PNG Data URL. Returns null if the 2D rendering context cannot be obtained, or if any other error occurs during encoding.

Implementation

Future<String?> encodeImageToDataURL(Images images, [int frame = 0]) async {
  var completer = Completer<String?>();

  Function(Images images, int frame)? encodeImage;

  encodeImage = (Images images, int frame) {
    if (images.isLoading) {
      Timer(Duration(milliseconds: 500), () {
        encodeImage!(images, frame);
      });
      return;
    }

    try {
      var image = images[frame];
      final canvas = HTMLCanvasElement();
      canvas.width = image.width;
      canvas.height = image.height;
      final ctx = canvas.getContext('2d') as CanvasRenderingContext2D?;

      if (ctx == null) {
        warn("Could not retrieve 2D Context");
        completer.complete(null);
        return;
      }

      final imageData = ctx.createImageData(image.width.toJS, image.height);
      for (int y = 0; y < canvas.height; ++y) {
        for (int x = 0; x < canvas.width; ++x) {
          var offsetX = image.sourceRect.x;
          var offsetY = image.sourceRect.y;

          var srcIdx = ((y * canvas.width) + x) * 4;
          var dstIdx = (((offsetY + y) * image.texture.width) + (x + offsetX)) * 4;

          imageData.data.toDart[srcIdx++] = image.texture.pixelData[dstIdx++];
          imageData.data.toDart[srcIdx++] = image.texture.pixelData[dstIdx++];
          imageData.data.toDart[srcIdx++] = image.texture.pixelData[dstIdx++];
          imageData.data.toDart[srcIdx++] = image.texture.pixelData[dstIdx++];
        }
      }
      ctx.putImageData(imageData, 0, 0);

      completer.complete(canvas.toDataURL('image/png'));
    } catch (e) {
      error("[BullseyeApp] Error encoding image to data URL: $e");
      completer.complete(null);
    }
  };

  encodeImage(images, frame);

  return completer.future;
}