How to Add PDF Annotations to Scanned Documents with JavaScript

Dynamsoft Document Viewer is an SDK providing a set of viewers for document images. It has added an annotation feature since v2.0, which makes it easy to create a document scanning solution along with the following SDKs:

In this article, we are going to talk about what annotations it provides, what use cases it can do and some codes for illustration.

Online demo with document scanning and annotation features

Supported Annotations

Currently, it can annotate with shapes, free drawing, text and images.

Shapes:

  • Rectangle
  • Ellipse
  • Polygon
  • Polyline
  • Line

Text:

  • TextBox
  • TextTypewriter

Other:

  • Ink (freehand drawing)
  • Stamp (custom image)

Some Use Cases

Using the annotation feature, we can achieve some common tasks in document management.

  1. Add comments and highlights.

    rectangles and text

  2. Add barcodes or QR codes for document identification.

    barcode

  3. Redact sensitive information like the contact’s name or photo.

    redact

  4. Proofread a manuscript by drawing markups.

    proofreading

  5. Add stamps for specifying the document’s status.

    stamp and images

Code in Action

Let’s check out some codes to add annotations.

Add Dynamsoft Document Viewer

To use Dynamsoft Document Viewer in a web page, include the following files:

<script src="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@latest/dist/ddv.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@latest/dist/ddv.css">

Then initialize it with the following code:

Dynamsoft.DDV.Core.license = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ=="; // Public trial license which is valid for 24 hours
Dynamsoft.DDV.Core.engineResourcePath = "https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@latest/dist/engine";// Lead to a folder containing the distributed WASM files
await Dynamsoft.DDV.Core.loadWasm();
await Dynamsoft.DDV.Core.init(); 

You can apply for a license here.

Create an Edit Viewer for Annotating

We need to create an instance of Edit Viewer to view and add annotations.

const editViewerUiConfig = {
    type: Dynamsoft.DDV.Elements.Layout,
    flexDirection: "column",
    className: "ddv-edit-viewer-mobile",
    children: [
        {
            type: Dynamsoft.DDV.Elements.Layout,
            className: "ddv-edit-viewer-header-mobile",
            children: [
                Dynamsoft.DDV.Elements.Pagination,
                {
                    type: Dynamsoft.DDV.Elements.Button,
                    className: "ddv-button-done",
                    events:{
                        click: "close"
                    }
                }
            ],
        },
        Dynamsoft.DDV.Elements.MainView,
        {
            type: Dynamsoft.DDV.Elements.Layout,
            className: "ddv-edit-viewer-footer-mobile",
            children: [
                Dynamsoft.DDV.Elements.DisplayMode,
                Dynamsoft.DDV.Elements.RotateLeft,
                Dynamsoft.DDV.Elements.Crop,
                Dynamsoft.DDV.Elements.Filter,
                Dynamsoft.DDV.Elements.Undo,
                Dynamsoft.DDV.Elements.Delete,
                Dynamsoft.DDV.Elements.AnnotationSet
            ],
        },
    ],
};

// Create an edit viewer
editViewer = new Dynamsoft.DDV.EditViewer({
    container: "fullscreenContainer",
    groupUid: captureViewer.groupUid,
    uiConfig: editViewerUiConfig
});

// Configure image filter feature which is in edit viewer
Dynamsoft.DDV.setProcessingHandler("imageFilter", new Dynamsoft.DDV.ImageFilter());

Open the Edit Viewer, click the annotation icon and we can start adding annotations via the UI.

edit viewer

Add Annotations via Code

Apart from using the Edit Viewer, we can also add annotations via code.

For example, we need to redact some words like names. We can use OCR to get the bounding boxes of the words and add rectangle annotations accordingly. Please note that the coordinates should be in point and we need to convert pixels to points first.

const pageUid = editViewer.indexToUid(pageIndex);
const pageData = await doc.getPageData(pageUid);
const scaleX = pageData.mediaBox.width / pageData.raw.width; //for converting pixels to points
const scaleY = pageData.mediaBox.height / pageData.raw.height;
const options = {
  x: bbox.x0*scaleX,
  y: bbox.y0*scaleY,
  width: (bbox.x1 - bbox.x0)*scaleX,
  height: (bbox.y1 - bbox.y0)*scaleY,
  borderColor: "black",
  background: "black"
  //flags:{readOnly:true} //enable read only if you do not need to interact with the annotation
}
const rect = Dynamsoft.DDV.annotationManager.createAnnotation(pageUid, "rectangle",options);

You can add other types of annotations. Check out the docs for details.

Save as PDF

We can save the images as a PDF file with annotations.

const pdfSettings = {
  saveAnnotation: "annotation"
};
const blob = await doc.saveToPdf(pdfSettings);

We can specify how to save the annotations using the saveAnnotation setting. It has the following options:

  • none: not saving annotations.
  • image: saving annotations as a part of image.
  • annotation: saving annotations as pdf annotations.
  • flatten: saving annotations as page content.

If we choose the annotation option, we can continue editing the annotations later using Dynamsoft Document Viewer or other PDF editors like Adobe Acrobat.

Load PDF with Annotations

If we have an existing PDF file with annotations, we can load it with the following code:

let pdfSource = {
  fileData:blob,
  renderOptions:{
    renderAnnotations:Dynamsoft.DDV.EnumAnnotationRenderMode.LOAD_ANNOTATIONS
  }
}
await doc.loadSource(pdfSource);

There are several modes for loading the annotations:

enum EnumAnnotationRenderMode {
    NO_ANNOTATIONS = "noAnnotations", // default, means that the annotations in the PDF file will not be loaded
    RENDER_ANNOTATIONS = "renderAnnotations", // means that the annotations in the PDF file will be rendered
    LOAD_ANNOTATIONS = "loadAnnotations", // means that the annotations in the PDF file will be loaded normally, a valid PDF Annotation license is requested
}

If we choose the LOAD_ANNOTATIONS mode, we can continue editing the existing annotations in a PDF file.

Source Code

Check out the source code of the demo to have a try.

https://github.com/tony-xlh/document-viewer-samples/tree/main/scan-and-annotate