How to Develop Web Document Image Viewer, Editor and Converter in JavaScript

Xiao Ling - Jan 5 - - Dev Community

A Web Document Viewer is a software tool enabling users to view and edit various document types, including PDF, JPEG, PNG, and TIFF, directly within a web browser. Recently, Dynamsoft released a JavaScript Document Viewer SDK, designed to expedite the development of web-based document management applications. In this article, we will explore the SDK's APIs and demonstrate how to develop a web document viewer, editor, and converter step by step.

web image editor

Online Demo

https://yushulx.me/web-twain-document-scan-management/examples/document_viewer/

Prerequisites

  • SDK Package: You can download the SDK package from Dynamsoft Download Center. This SDK package includes the following files:

    ├── engine
    |   ├── ddv-crypto.wasm
    |   ├── ddv-imagecore.wasm
    |   ├── ddv-imageio.wasm
    |   ├── ddv-imageio.worker.js
    |   ├── ddv-imageproc.wasm
    |   ├── ddv-imageproc-simd.wasm
    |   ├── ddv-pdfreader.wasm
    |   ├── dls.license.dialog.html
    ├── ddv.css
    ├── ddv.es.js
    ├── ddv.js
    |── index.d.ts
    

    Alternatively, you have the option to incorporate the SDK hosted on jsDelivr or UNPKG CDN into your web application. The CDN URLs are as follows:

    jsDelivr

    <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">
    

    UNPKG

    <script src="https://unpkg.com/dynamsoft-document-viewer@latest/dist/ddv.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/dynamsoft-document-viewer@latest/dist/ddv.css">
    
  • SDK License: To try the SDK for free, request a trial license key.

Initializing Dynamsoft Document Viewer SDK with a License Key

To initialize the SDK, add the following JavaScript code to your web page, replacing LICENSE-KEY with your actual license key.

try {
    Dynamsoft.DDV.Core.license = license;
    Dynamsoft.DDV.Core.engineResourcePath = "https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@1.1.0/dist/engine";
    await Dynamsoft.DDV.Core.init();
    Dynamsoft.DDV.setProcessingHandler("imageFilter", new Dynamsoft.DDV.ImageFilter());
    docManager = Dynamsoft.DDV.documentManager;


} catch (error) {
    console.error(error);
}
Enter fullscreen mode Exit fullscreen mode
  • The engineResourcePath specifies the path to the engine, which could be a local path or a CDN URL. The init method initializes the SDK engine and returns a promise.
  • Use the setProcessingHandler method to configure the image filter. The ImageFilter class is used to process image data before rendering it on the canvas. You can apply filters to the image, such as grayscale, black and white, shadow removal, and more.

Document Data Management

The diagram below illustrates the relationship among DocumentManager, Document, and Page.

document page

The IDocument interface is utilized for managing document data. Create a document instance by invoking the createDocument method on the documentManager object.

let doc = docManager.createDocument();
Enter fullscreen mode Exit fullscreen mode

A new document contains a unique ID generated automatically. You can get the ID through the uid property.

let currentUid = doc.uid;
Enter fullscreen mode Exit fullscreen mode

Use the loadSource method in the IDocument interface to load a document source. It accepts a Blob object as the parameter. The following code snippet shows how to create a document and add a file to it.

<input type="file" id="fileInput" accept="application/pdf,image/png,image/jpeg,image/tiff">

<script>
document.getElementById('fileInput').addEventListener('change', function (event) {
    if (!docManager) return;
    const file = event.target.files[0];
    if (!file) {
        console.log("No file selected.");
        return;
    }

    const reader = new FileReader();
    reader.onload = function (e) {
        const blob = new Blob([e.target.result], { type: file.type });

        async function createDoc() {
            let doc = null;
            if (!currentUid) {
                doc = docManager.createDocument();
                currentUid = doc.uid;
                openDocument(currentUid);
            }
            else {
                doc = docManager.getDocument(currentUid);
            }
            let pages = await doc.loadSource(blob);
        }
        createDoc();
    };

    reader.onerror = function (err) {
        console.error("Error reading file", err);
    };

    reader.readAsArrayBuffer(file);
});
</script>
Enter fullscreen mode Exit fullscreen mode

When you get a new blob, you have the option to either add it to a new document using createDocument(), or to an existing document with getDocument(currentUid). The loadSource() method, when invoked, loads a blob and returns an array of page IDs. For instance, if the blob is a JPEG file, this method returns a single page ID. For a 10-page PDF file, it returns 10 page IDs.

The document interface offers various methods for manipulating pages, such as:

  • getPageData(pageUid: string): Promise<PageData>
  • updatePage(pageUid: string, data: Blob): Promise<boolean>
  • setPageCustomData(pageUid: string, data: any): Promise<boolean>
  • getPageCustomData(pageUid: string): Promise<any>
  • deletePages(indices: number[]): boolean

Implementing Image Converter for PDF, PNG, JPEG, and TIFF

The built-in methods saveToPdf, saveToJpeg, saveToTiff, and saveToPng of the IDocument interface can be utilized to convert a document to a specific format.

function saveBlob(blob, fileName) {
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = fileName;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
}

document.getElementById('saveButton').addEventListener('click', async () => {
    if (!docManager && !currentUid) return;

    let format = document.getElementById('format').value;
    let filename = document.getElementById('filename').value;

    if (!filename) {
        filename = "test";
    }

    let result = null;
    let doc = docManager.getDocument(currentUid);
    switch (format) {
        case "pdf":
            const pdfSettings = {
                author: "Dynamsoft",
                compression: "pdf/jpeg",
                pageType: "page/a4",
                creator: "DDV",
                creationDate: "D:20230101085959",
                keyWords: "samplepdf",
                modifiedDate: "D:20230101090101",
                producer: "Dynamsoft Document Viewer",
                subject: "SamplePdf",
                title: "SamplePdf",
                version: "1.5",
                quality: 90,
            }
            result = await doc.saveToPdf(pdfSettings);
            saveBlob(result, filename + "." + format);
            break;
        case "png":
            {
                let count = doc.pages.length;

                for (let i = 0; i < count; i++) {
                    result = await doc.saveToPng(i);
                    saveBlob(result, filename + i + "." + format);
                }
            }

            break;
        case "jpeg":
            {
                const settings = {
                    quality: 80,
                };

                let count = doc.pages.length;

                for (let i = 0; i < count; i++) {
                    result = await doc.saveToJpeg(i, settings);
                    saveBlob(result, filename + i + "." + format);
                }
            }

            break;
        case "tiff":
            const customTag1 = {
                id: 700,
                content: "Created By Dynamsoft",
                contentIsBase64: false,
            }

            const tiffSettings = {
                customTag: [customTag1],
                compression: "tiff/auto",
            }
            result = await doc.saveToTiff(tiffSettings);
            saveBlob(result, filename + "." + format);
            break;
    }
});
Enter fullscreen mode Exit fullscreen mode

web image converter

Editing Document Images in Viewers

The Dynamsoft Document Viewer SDK stands out not only for its data operation APIs but also for its provides UI components and image editing tools, such as crop, rotate, flip, among others, enabling developers to swiftly build a document viewer. The primary UI components include:

Edit Viewer

Edit Viewer is a UI component enabling users to view and edit document images. This component offers a suite of image editing tools including crop, rotate, flip, among others. The following code snippet shows how to create an edit viewer and add it to the web page.

<div id="edit-viewer"></div>

<script> 
let editContainer = document.getElementById("edit-viewer");
let editViewer = new Dynamsoft.DDV.EditViewer({
        container: editContainer,
    });
</script>
Enter fullscreen mode Exit fullscreen mode

edit viewer

Besides the editing tools, the Edit Viewer also features buttons for file import, file export, and printing.

Capture Viewer

Capture Viewer is a UI component designed for capturing images directly from a camera.

<div id="capture-viewer"></div>

<script> 
let captureContainer = document.getElementById("capture-viewer");
let captureViewer = new Dynamsoft.DDV.CaptureViewer({
        container: captureContainer
    });
const cameras = await captureViewer.getAllCameras();
if (cameras.length) {
    await captureViewer.selectCamera(cameras[0]);
}
captureViewer.play({
    resolution: [1920, 1080],
}).catch(err => {
    alert(err.message)
});
</script>
Enter fullscreen mode Exit fullscreen mode

capture viewer

Perspective Viewer

Perspective Viewer is a UI component enabling perspective correction on document images.

<div id="perspective-viewer"></div>

<script>
let perspectiveContainer = document.getElementById("perspective-viewer");
perspectiveViewer = new Dynamsoft.DDV.PerspectiveViewer({
    container: perspectiveContainer
});
</script>
Enter fullscreen mode Exit fullscreen mode

perspective viewer

Browse Viewer

Browse Viewer is a UI component facilitating the browsing and selection of document images.

<div id="browse-viewer"></div>

<script>
let browseContainer = document.getElementById("browse-viewer");
browseViewer = new Dynamsoft.DDV.BrowseViewer({
    container: browseContainer
});
browseViewer.multiselectMode = true;
</script>
Enter fullscreen mode Exit fullscreen mode

browse viewer

Source Code

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

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player