How to Develop Web Document Image Viewer, Editor and Converter in JavaScript
Tags: webdev, javascript, programming, document
Published: 2024-01-05 06:02:43

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](https://www.dynamsoft.com/document-viewer/docs/introduction/index.html), 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](https://www.dynamsoft.com/codepool/img/2024/01/web-document-viewer.png)

## Online Demo
[https://yushulx.me/web-twain-document-scan-management/examples/document_viewer/](https://yushulx.me/web-twain-document-scan-management/examples/document_viewer/)

## Prerequisites
- **SDK Package**: You can download the SDK package from [Dynamsoft Download Center](https://www.dynamsoft.com/document-viewer/downloads/1000031-confirmation/). This SDK package includes the following files:
    
    ```bash
    ├── 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**

    ```html
    <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**
    
    ```html
    <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](https://www.dynamsoft.com/customer/license/trialLicense/?product=mwc).

## 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.

```js
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);
}
```

- 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](https://www.dynamsoft.com/document-viewer/docs/assets/imgs/doc&page.png)

The [IDocument](https://www.dynamsoft.com/document-viewer/docs/api/interface/idocument/index.html) interface is utilized for managing document data. Create a document instance by invoking the `createDocument` method on the `documentManager` object.

```js
let doc = docManager.createDocument();
```

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

```js
let currentUid = doc.uid;
```


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.

```js
<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>
```

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](https://www.dynamsoft.com/document-viewer/docs/api/interface/idocument/index.html#savetopdf), [saveToJpeg](https://www.dynamsoft.com/document-viewer/docs/api/interface/idocument/index.html#savetojpeg), [saveToTiff](https://www.dynamsoft.com/document-viewer/docs/api/interface/idocument/index.html#savetotiff), and [saveToPng](https://www.dynamsoft.com/document-viewer/docs/api/interface/idocument/index.html#savetopng) of the `IDocument` interface can be utilized to convert a document to a specific format.


```js
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;
    }
});
```

![web image converter](https://www.dynamsoft.com/codepool/img/2024/01/web-image-converter.png)

## 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](https://www.dynamsoft.com/document-viewer/docs/features/viewers/editviewer.html)
- [Capture Viewer](https://www.dynamsoft.com/document-viewer/docs/features/viewers/captureviewer.html)
- [Perspective Viewer](https://www.dynamsoft.com/document-viewer/docs/features/viewers/perspectiveviewer.html)
- [Browse Viewer](https://www.dynamsoft.com/document-viewer/docs/features/viewers/others.html)

### Edit Viewer
[Edit Viewer](https://www.dynamsoft.com/document-viewer/docs/features/viewers/editviewer.html) 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.

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

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

![edit viewer](https://www.dynamsoft.com/codepool/img/2024/01/edit-viewer.png)

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

### Capture Viewer

[Capture Viewer](https://www.dynamsoft.com/document-viewer/docs/features/viewers/captureviewer.html) is a UI component designed for capturing images directly from a camera.


```js
<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>
```

![capture viewer](https://www.dynamsoft.com/codepool/img/2024/01/capture-viewer.png)

### Perspective Viewer

[Perspective Viewer](https://www.dynamsoft.com/document-viewer/docs/features/viewers/perspectiveviewer.html) is a UI component enabling perspective correction on document images.


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

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

![perspective viewer](https://www.dynamsoft.com/codepool/img/2024/01/perspective-viewer.png)


### Browse Viewer

[Browse Viewer](https://www.dynamsoft.com/document-viewer/docs/features/viewers/others.html#browse-viewer) is a UI component facilitating the browsing and selection of document images.

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

<script>
let browseContainer = document.getElementById("browse-viewer");
browseViewer = new Dynamsoft.DDV.BrowseViewer({
    container: browseContainer
});
browseViewer.multiselectMode = true;
</script>
```
    
![browse viewer](https://www.dynamsoft.com/codepool/img/2024/01/browse-viewer.png)

## Source Code
[https://github.com/yushulx/web-twain-document-scan-management/tree/main/examples/document_viewer](https://github.com/yushulx/web-twain-document-scan-management/tree/main/examples/document_viewer)