Export an Ink Annotation as an Image

Ink annotations are rendered as SVG elements on the DOM. To export an image from an ink annotation, retrieve the SVG and then either download it with an image/svg+xml MIME type, or render it to a canvas as a PNG:

// "annotation" is a reference to our ink annotation.

const svgSelector = `.PSPDFKit-Ink-Annotation[data-annotation-id="${annotation.id}"] svg`;

// Wait until the SVG is rendered.
const observer = new MutationObserver(async () => {
  const svgEl = instance.contentDocument.querySelector(svgSelector);
  if (svgEl) {
    observer.disconnect();

    // We need to set the first "g" element to transparent.
    svgEl.querySelector("g").style.fill = "transparent";

    // Apply 'round' `strokeLinecap` and `strokeLinejoin` styles to all
    // 'path' elements in 'svgEl' for smooth line endings and joints.
    const paths = svgEl.querySelectorAll("path");

    paths.forEach((path) => {
      path.style.strokeLinecap = "round";
      path.style.strokeLinejoin = "round";
    });

    // Serialize to XML.
    const svg = new XMLSerializer().serializeToString(svgEl);

    // Download the SVG.
    const link = document.createElement("a");
    link.href = `data:svg+xml; charset=utf-8, ${svg}`;
    link.download = `${annotation.id}.svg`;
    link.click();

    // Instead of downloading the SVG, we can instead
    // render it to a canvas and export the blob
    // as a PNG.
  }
});
observer.observe(page, { subtree: true, childList: true });

If you’d like to export it as a PNG instead, we can continue from the previous snippet by — instead of downloading the SVG — taking the svg reference, rendering it to a canvas, and then exporting the blob:

const img = new Image();
img.src = `data:image/svg+xml; charset=utf-8, ${svg}`;
img.onload = () => {
  const canvas = document.createElement("canvas");
  canvas.width = img.naturalWidth;
  canvas.height = img.naturalHeight;
  const ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0);
  canvas.toBlob(
    async (blob) => {
      // We can process the blob as we'd like here.
    },
    { type: "image/png" }
  );
};

This has been tested with PSPDFKit for Web 2020.2.6