Creating an option for watermark on photos

I’m building a field app for technicians of Trinidad & Tobago where technicians take photos as proof of work.

I need the ability to embed a watermark directly onto the image file (not just overlay in UI) that includes:

  • Timestamp
  • GPS location
  • Status / metadata

This is critical because the image may leave the app and needs to retain verification data.

You can do something like this in a javascript column, and then display the result of that javascript column as an image.

return (async () => {
  const url = p1;
  const text = p2 || "";

  let config = {};
  try {
    config = p3 ? JSON.parse(p3) : {};
  } catch (e) {}

  const fontSize = config.fontSize || 24;
  const color = config.color || "rgba(255,255,255,0.7)";
  const position = config.position || "bottom-right";

  return new Promise((resolve) => {
    const img = new Image();
    img.crossOrigin = "anonymous";

    img.onload = function () {
      const canvas = document.createElement("canvas");
      const ctx = canvas.getContext("2d");

      canvas.width = img.width;
      canvas.height = img.height;

      ctx.drawImage(img, 0, 0);

      ctx.font = `${fontSize}px sans-serif`;
      ctx.fillStyle = color;
      ctx.textBaseline = "bottom";

      const padding = 10;
      const textWidth = ctx.measureText(text).width;

      let x, y;

      switch (position) {
        case "bottom-left":
          x = padding;
          y = canvas.height - padding;
          break;
        case "top-left":
          x = padding;
          y = fontSize + padding;
          break;
        case "top-right":
          x = canvas.width - textWidth - padding;
          y = fontSize + padding;
          break;
        case "center":
          x = (canvas.width - textWidth) / 2;
          y = canvas.height / 2;
          break;
        default:
          x = canvas.width - textWidth - padding;
          y = canvas.height - padding;
      }

      ctx.shadowColor = "rgba(0,0,0,0.5)";
      ctx.shadowBlur = 4;

      ctx.fillText(text, x, y);

      resolve(canvas.toDataURL("image/png"));
    };

    img.onerror = function () {
      resolve(null);
    };

    img.src = url;
  });
})();