DEV Community

Xiao Ling
Xiao Ling

Posted on • Edited on • Originally published at dynamsoft.com

How to Read DataMatrix and Other 1D/2D Barcodes from PDF Files in HTML5 and JavaScript

In today's digital world, barcodes have become an integral part of many industries, including healthcare, logistics, retail, and more. A significant use case is in medical forms, where 1D and 2D barcodes, such as DataMatrix, are embedded within PDF documents. These barcodes contain crucial information such as patient identification, medical codes, and treatment details, ensuring a smooth and efficient workflow. In this article, we will demonstrate how to extract and read DataMatrix and other 1D/2D barcodes from PDF files using HTML5 and JavaScript.

Demo Video: Read DataMatrix from PDF Files

Online Demo

https://yushulx.me/web-document-annotation/

Prerequisites

Steps to Read DataMatrix and Other Barcodes from PDF Files

In a previous article, we created a web-based PDF document editor with barcode insertion capabilities using Dynamsoft Document Viewer. The source code from that article will be used as the starting point for this tutorial.

In the latest version of Dynamsoft Document Viewer, a flattened property has been added to the annotation object, making it more flexible and efficient to flatten target annotations into a document. When barcodes are inserted as annotations into PDF documents, they are typically stored as vector graphics and are unreadable until they are flattened into the document. This process converts the vector graphics into raster images.

Step 1: Flatten 1D/2D Barcode Annotations in PDF Files

If you don't have a PDF document with barcode annotations, you can create one as follows:

  1. Deploy the project and open the web-based PDF document editor in your browser.

    python -m http.server 8000
    
  2. Click load an image file to load a PDF or other image file into the document viewer.

  3. Click generate DataMatrix to insert a DataMatrix or other barcode into the document.

  4. Click save PDF files to save the modified PDF file to your local disk.

    save PDF with password

    Explanation

    • The password is optional. You can encrypt the PDF file with a password.
    • The annotation type specifies how to save the annotations. The default value is None, which means the annotations will not be saved in the PDF file. Other options include Image, Annotation, and Flattened. Select Annotation to save the barcode annotations to ensure they can be edited when importing the PDF file back into the document viewer.

Next, load the saved PDF file into the document viewer. The default built-in loading method does not support entering the PDF password, so we need to customize the loading button to prompt for the password.

  1. Create a prompt container in index.html:

    <div id="password-input" class="overlay">
        <div class="popup">
            <h2>Input PDF Password</h2>
            <form id="passwordForm">
                <div class="form-group">
                    <label for="password">Password:</label>
                    <input type="password" id="pdfpassword" name="pdfpassword" placeholder="Enter password" required>
                </div>
                <div class="popup-buttons">
                    <button type="button" id="submitPassword">Submit</button>
                    <button type="button" id="cancelPassword">Cancel</button>
                </div>
            </form>
        </div>
    </div>
    
  2. Create an element object and insert it into the UI configuration in main.js:

    const loadButton = {
        type: Dynamsoft.DDV.Elements.Button,
        className: "ddv-button ddv-load-image",
        tooltip: "Load a document",
        events: {
            click: "loadDocument",
        },
    }
    
    const pcEditViewerUiConfig = {
        type: Dynamsoft.DDV.Elements.Layout,
        flexDirection: "column",
        className: "ddv-edit-viewer-desktop",
        children: [
            {
                type: Dynamsoft.DDV.Elements.Layout,
                className: "ddv-edit-viewer-header-desktop",
                children: [
                    ...
                    {
                        type: Dynamsoft.DDV.Elements.Layout,
                        children: [
                            {
                                type: Dynamsoft.DDV.Elements.Pagination,
                                className: "ddv-edit-viewer-pagination-desktop",
                            },
                            loadButton,
                            downloadButton,
                        ],
                    },
                ],
            },
            Dynamsoft.DDV.Elements.MainView,
        ],
    };
    
  3. Handle the loadDocument event to load the PDF file with a password prompt in main.js:

    editViewer.on("loadDocument", loadDocument);
    
    function loadDocument() {
        let fileInput = document.createElement("input");
        fileInput.type = "file";
        fileInput.accept = ".jpg,.jpeg,.png,.tiff,.tif,.bmp,.pdf";
        fileInput.onchange = async (e) => {
            let file = e.target.files[0];
            if (!file) return;
    
            const reader = new FileReader();
    
            reader.onload = async function (e) {
                fileBlob = new Blob([e.target.result], { type: file.type });
                load(fileBlob);
            };
    
            reader.readAsArrayBuffer(file);
    
        };
        fileInput.click();
    }
    
    async function load(blob, password) {
        try {
            if (!currentDoc) {
                currentDoc = Dynamsoft.DDV.documentManager.createDocument({
                    name: Date.now().toString(),
                    author: "DDV",
                });
            }
    
            const source = {
                fileData: blob,
                password: password,
                renderOptions: {
                    renderAnnotations: "loadAnnotations"
                }
            };
            await currentDoc.loadSource([source]);
            editViewer.openDocument(currentDoc);
        } catch (error) {
            console.error(error);
    
            // PDF is encrypted
            if (error.cause.code == -80202) {
                document.getElementById("password-input").style.display = "flex";
            }
        }
    }
    
    let fileBlob = null;
    const submitPasswordButton = document.getElementById('submitPassword');
    const cancelPasswordButton = document.getElementById('cancelPassword');
    
    cancelPasswordButton.addEventListener('click', () => {
        document.getElementById("password-input").style.display = "none";
    }
    );
    
    submitPasswordButton.addEventListener('click', async () => {
        const password = document.getElementById('pdfpassword').value;
        load(fileBlob, password);
        document.getElementById("password-input").style.display = "none";
    });
    

    Explanation

    • loadDocument(): Create an input element for loading PDF files. Use FileReader to read the file content and convert it into a blob.
    • load(blob, password): Load the PDF file into the document viewer. If the PDF is encrypted, display a password input element.

    load PDF files with password

As a PDF file is loaded into the document viewer, change the status of all annotations to flattened. This creates a raster image for barcode detection later.

let currentPageId = currentDoc.pages[editViewer.getCurrentPageIndex()];
let annotations = Dynamsoft.DDV.annotationManager.getAnnotationsByPage(currentPageId);

for (let i = 0; i < annotations.length; i++) {
    annotations[i].flattened = true;
}
const image = await editViewer.currentDocument.saveToJpeg(editViewer.getCurrentPageIndex(), settings);
Enter fullscreen mode Exit fullscreen mode

Step 2: Read DataMatrix and Other Barcodes with Dynamsoft Barcode Reader

  1. Include the Dynamsoft Barcode Reader Bundle in index.html:

    <script src="https://cdn.jsdelivr.net/npm/dynamsoft-barcode-reader-bundle@10.4.2002/dist/dbr.bundle.js"></script>
    
  2. Create a CaptureVisionRouter object in main.js:

    cvRouter = await Dynamsoft.CVR.CaptureVisionRouter.createInstance();
    
  3. Read the barcodes from the raster image in main.js:

    const result = await cvRouter.capture(image, "ReadBarcodes_Default");
    

    The second parameter is the a template name preset in the Capture Vision Router. Click here to learn more about the preset templates.

  4. Display the barcode results by drawing annotations in main.js:

    for (let item of result.items) {
        if (item.type !== Dynamsoft.Core.EnumCapturedResultItemType.CRIT_BARCODE) {
            continue;
        }
        console.log(JSON.stringify(item));
        let text = item.text;
        let points = item.location.points;
    
        let currentPageId = currentDoc.pages[editViewer.getCurrentPageIndex()];
        let pageData = await currentDoc.getPageData(currentPageId);
    
        // https://www.dynamsoft.com/document-viewer/docs/api/interface/annotationinterface/texttypewriterannotationoptions.html
        let textX = Math.min(points[0].x, points[1].x, points[2].x, points[3].x) / pageData.display.width * pageData.mediaBox.width;
        let textY = Math.min(points[0].y, points[1].y, points[2].y, points[3].y) / pageData.display.height * pageData.mediaBox.height;
    
        const textTypewriterOptions = {
            x: textX < 0 ? 0 : textX,
            y: textY - 15 < 0 ? 0 : textY - 15,
            textContents: [{ content: text, color: "rgb(255,0,0)" }],
            flags: {
                print: false,
                noView: false,
                readOnly: false,
    
            }
        }
    
        // https://www.dynamsoft.com/document-viewer/docs/api/class/annotationmanager.html#createAnnotation
        let textTypewriter = await Dynamsoft.DDV.annotationManager.createAnnotation(currentPageId, "textTypewriter", textTypewriterOptions)
        savedAnnotations.push(textTypewriter);
        textTypewriter['name'] = 'overlay';
    
        // https://www.dynamsoft.com/document-viewer/docs/api/interface/annotationinterface/polygonannotationoptions.html
        const polygonOptions = {
            points: points.map(p => {
                return {
                    x: p.x / pageData.display.width * pageData.mediaBox.width,
                    y: p.y / pageData.display.height * pageData.mediaBox.height
                }
            }),
            borderColor: "rgb(255,0,0)",
            flags: {
                print: false,
                noView: false,
                readOnly: false,
    
            }
        }
    
        let polygon = Dynamsoft.DDV.annotationManager.createAnnotation(currentPageId, "polygon", polygonOptions);
        polygon['name'] = 'overlay';
        savedAnnotations.push(polygon);
    }
    

    read DataMatrix and barcodes from PDF files

Source Code

https://github.com/yushulx/web-twain-document-scan-management/tree/main/examples/document_annotation

Top comments (0)