apply method

  1. @override
void apply(
  1. BitmapData bitmapData, [
  2. Rectangle<num>? rectangle
])
override

Implementation

@override
void apply(BitmapData bitmapData, [Rectangle<num>? rectangle]) {
  final renderTextureQuad = rectangle == null
      ? bitmapData.renderTextureQuad
      : bitmapData.renderTextureQuad.cut(rectangle);

  final mapImageData = this.bitmapData.renderTextureQuad.getImageData();
  final srcImageData = renderTextureQuad.getImageData();
  final dstImageData = renderTextureQuad.createImageData();
  final mapWidth = mapImageData.width;
  final mapHeight = mapImageData.height;
  final srcWidth = srcImageData.width;
  final srcHeight = srcImageData.height;
  final dstWidth = dstImageData.width;
  final dstHeight = dstImageData.height;

  final mapData = mapImageData.data;
  final srcData = srcImageData.data;
  final dstData = dstImageData.data;

  final vxList = renderTextureQuad.vxListQuad;
  final pixelRatio = renderTextureQuad.pixelRatio;
  final scaleX = pixelRatio * this.scaleX;
  final scaleY = pixelRatio * this.scaleX;
  final channelX = BitmapDataChannel.getCanvasIndex(BitmapDataChannel.RED);
  final channelY = BitmapDataChannel.getCanvasIndex(BitmapDataChannel.GREEN);

  // dstPixel[x, y] = srcPixel[
  //     x + ((colorR(x, y) - 128) * scaleX) / 256,
  //     y + ((colorG(x, y) - 128) * scaleY) / 256)];

  final matrix = this.matrix.cloneInvert();
  matrix.prependTranslation(vxList[0], vxList[1]);

  for (var dstY = 0; dstY < dstHeight; dstY++) {
    var mx = dstY * matrix.c + matrix.tx;
    var my = dstY * matrix.d + matrix.ty;
    for (var dstX = 0;
        dstX < dstWidth;
        dstX++, mx += matrix.a, my += matrix.b) {
      var mapX = mx.round();
      var mapY = my.round();
      if (mapX < 0) mapX = 0;
      if (mapY < 0) mapY = 0;
      if (mapX >= mapWidth) mapX = mapWidth - 1;
      if (mapY >= mapHeight) mapY = mapHeight - 1;
      final mapOffset = (mapX + mapY * mapWidth) << 2;
      final srcX =
          dstX + ((mapData[mapOffset + channelX] - 127) * scaleX) ~/ 256;
      final srcY =
          dstY + ((mapData[mapOffset + channelY] - 127) * scaleY) ~/ 256;
      if (srcX >= 0 && srcY >= 0 && srcX < srcWidth && srcY < srcHeight) {
        final srcOffset = (srcX + srcY * srcWidth) << 2;
        final dstOffset = (dstX + dstY * dstWidth) << 2;
        if (srcOffset > srcData.length - 4) continue;
        if (dstOffset > dstData.length - 4) continue;
        dstData[dstOffset + 0] = srcData[srcOffset + 0];
        dstData[dstOffset + 1] = srcData[srcOffset + 1];
        dstData[dstOffset + 2] = srcData[srcOffset + 2];
        dstData[dstOffset + 3] = srcData[srcOffset + 3];
      }
    }
  }

  renderTextureQuad.putImageData(dstImageData);
}