Export ink annotation as image

Q: How can I export an image from an ink annotation?

A: Ink annotations are rendered as SVG elements on the DOM. You can get that SVG and then either download it as a svg+xml file, oe render it to a canvas as a PNG.

Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// "annotation" is a reference to our ink annotation

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

// Wait until 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";

    // 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:

Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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