async runWithInputs()

in src/nodes/client/background-removal.ts [85:159]


  async runWithInputs(inputs: Inputs, services: Services) {
    const { image, modelid, quantized, device } = inputs;

    const _modelid = modelid?.trim();

    if (!image?.canvasId) {
      // No input node
      this.dispatchEvent(
        new CustomEvent("outputs", { detail: { foreground: null } })
      );
      return;
    }

    if (this.cachedResult && compareObjects(this.cachedInput, inputs)) {
      this.dispatchEvent(
        new CustomEvent("outputs", {
          detail: { foreground: this.cachedResult },
        })
      );
      return;
    }
    this.cachedInput = inputs;

    // Clear masks
    // this.masks.innerHTML = '';

    const canvas = services.resourceService.get(
      image.canvasId
    ) as HTMLCanvasElement;
    const data = canvas.toDataURL();
    const [model, processor] = await this.getInstance(
      _modelid,
      quantized,
      device
    );

    // TODO: .fromCanvas() method
    const i = await RawImage.fromURL(data);

    // Preprocess image
    const { pixel_values } = await processor(i);

    // Predict alpha matte
    const { output } = await model({ input: pixel_values });

    // Resize mask back to original size
    const mask = await RawImage.fromTensor(
      output[0].mul(255).to("uint8")
    ).resize(i.width, i.height);

    // Create new canvas
    const c = document.createElement("canvas");
    c.width = i.width;
    c.height = i.height;
    const ctx = c.getContext("2d")!;

    // Draw original image output to canvas
    ctx.drawImage(i.toCanvas(), 0, 0);

    // Update alpha channel
    const pixelData = ctx.getImageData(0, 0, i.width, i.height);
    for (let i = 0; i < mask.data.length; ++i) {
      pixelData.data[4 * i + 3] = mask.data[i];
    }
    ctx.putImageData(pixelData, 0, 0);

    const out = {
      canvasId: services.resourceService.put(c),
    };

    const detail: Outputs = { foreground: out };
    this.cachedResult = out;

    this.dispatchEvent(new CustomEvent("outputs", { detail: detail }));
  }