How to Create a Blazor Web App for Document PDF Viewing and Annotation

Dynamsoft Document Viewer SDK provides a comprehensive set of APIs for viewing and annotating PDFs and images in web applications. By integrating the SDK into your Blazor web app, you can create a powerful document management system with advanced features such as PDF rendering, page navigation, image quality enhancement, and document saving. This article will guide you through the process of building a Blazor web app for PDF viewing and annotation using the Dynamsoft Document Viewer SDK.

Blazor Document PDF Viewer Demo Video

Online Demo

https://yushulx.me/blazor-barcode-mrz-document-scanner/

Prerequisites

  • Dynamsoft Document Viewer: This package offers JavaScript APIs for viewing and annotating a wide range of document formats, including PDFs and images like JPEG, PNG, TIFF, and BMP. Key features include PDF rendering, page navigation, image quality enhancement, and document saving capabilities. You can find the SDK on npm.

  • Dynamsoft Capture Vision Trial License: The trial license provides access to all features of the Dynamsoft Capture Vision Bundle, including Barcode, MRZ, Document recognition, and more, for a period of 30 days. You can apply for a trial license here.

Step 1: Integrate Dynamsoft Document Viewer into a Blazor WebAssembly Project

  1. Create a Blazor WebAssembly Project: Start a new Blazor WebAssembly project using Visual Studio or Visual Studio Code.
  2. Add the Dynamsoft Document Viewer Script and CSS: To enable the Dynamsoft Document Viewer, include its script and CSS in the wwwroot/index.html file:
     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@latest/dist/ddv.css">
     <script src="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@latest/dist/ddv.js"></script>
    

    Note: Including the CSS file is essential to ensure that the highly customized UI components of the viewer render correctly.

  3. Create a JavaScript File for C# and JavaScript Interop: Add a JavaScript file named jsInterop.js in the wwwroot folder and include it in the index.html:
     <script src="jsInterop.js"></script>
    
  4. Set the License: In jsInterop.js, define a setLicense function that sets the license key and configures the necessary resource paths:
     window.jsFunctions = {
         setLicense: async function setLicense(license) {
             try {
                 Dynamsoft.DDV.Core.engineResourcePath = "https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@latest/dist/engine";
                 Dynamsoft.License.LicenseManager.initLicense(license, true);
                 Dynamsoft.DDV.setProcessingHandler("imageFilter", new Dynamsoft.DDV.ImageFilter());
                 await Dynamsoft.DDV.Core.init();
    
             } catch (e) {
                 console.log(e);
                 return false;
             }
            
             return true;
         }
     };
    
  5. Update the Blazor Page to Enable SDK Activation: In the Pages/Home.razor file, add the following HTML and C# code to allow users to activate the SDK using a valid license key:

     @page "/"
     @inject IJSRuntime JSRuntime
        
     <PageTitle>Home</PageTitle>
        
     <p>Click <a href="https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform" target="_blank">here</a> to obtain a Dynamsoft Capture Vision Trial License.</p>
        
     <EditForm Model="@this">
         <InputText @bind-Value="LicenseKey" placeholder="Enter your license key" />
         <button type="button" class="btn btn-primary" @onclick="SetLicenseKey">Activate the SDK</button>
     </EditForm>
        
     @code {
         Boolean initialized = false;
        
         private string LicenseKey = "LICENSE-KEY";
        
         private async Task SetLicenseKey()
         {
             initialized = await JSRuntime.InvokeAsync<Boolean>("jsFunctions.setLicense", LicenseKey);
             StateHasChanged();
         }
     }
    

Step 2: Implement a Document Viewer Razor Page

Setting up a document viewer with the Dynamsoft Document Viewer SDK can be accomplished quickly by following the sample code provided in the SDK’s README file. Below are the steps to create a PDF viewer in just a few minutes.

  1. Create a Document Viewer Component: Create a new Razor component called DocumentViewer.razor in the Pages folder and add it to your navigation menu in NavMenu.razor:
     <div class="nav-item px-3">
         <NavLink class="nav-link" href="documentviewer">
             <span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Document Viewer
         </NavLink>
     </div>
    
  2. Implement the Document Viewer in DocumentViewer.razor: Add the following code in DocumentViewer.razor to set up the document viewer:

     @page "/documentviewer"
     @inject IJSRuntime JSRuntime
        
     @if (isLoading)
     {
         <div id="loading-indicator" class="loading-indicator">
             <div class="spinner"></div>
         </div>
     }
        
     <div id="@containerId" class="container"></div>
        
     @code {
         private Boolean isLoading = true;
         private String containerId = "document_viewer";
         protected override async Task OnAfterRenderAsync(bool firstRender)
         {
             if (firstRender)
             {
                 await JSRuntime.InvokeVoidAsync("jsFunctions.initDocumentViewer", containerId);
                 isLoading = false;
                 StateHasChanged();
             }
         }
     }
    
    

    Explanation

    • @page "/documentviewer" sets the route for the Razor component.
    • OnAfterRenderAsync() calls the JavaScript function initDocumentViewer when the page loads to initialize the document viewer.
    • The loading indicator is displayed until the document viewer is fully initialized.
  3. Add JavaScript Functions in jsInterop.js: Add the corresponding JavaScript functions in jsInterop.js:
     window.jsFunctions = {
         ...
         initDocumentViewer: async function (containerId) {
             if (!isInitialized) {
                 alert("Please set the license first.");
                 return;
             }
             try {
                 let config = Dynamsoft.DDV.getDefaultUiConfig("editViewer", { includeAnnotationSet: true });
                 let editViewer = new Dynamsoft.DDV.EditViewer({
                     container: containerId,
                     uiConfig: config,
                 });
             }
             catch (e) {
                 alert(e);
             }
         },
     };
    

    Explanation

    • initDocumentViewer() initializes the document viewer by binding it to the specified container and using the default UI configuration provided by the SDK.
    • The EditViewer instance is set up with tools for viewing and annotating PDFs and images, allowing developers to achieve full functionality with minimal code.

Step 3: Implement a Document Scanner Razor Page

Implementing a document scanner in Blazor is straightforward, especially if you leverage the existing .NET MAUI Blazor Hybrid App with the Dynamsoft Document Viewer SDK. You can find the source code on GitHub. Here’s how to migrate the code to your Blazor WebAssembly project:

  1. Create a Document Scanner Component: Create a new Razor component called DocumentScanner.razor in the Pages folder and add it to the navigation menu in NavMenu.razor:
     <div class="nav-item px-3">
         <NavLink class="nav-link" href="documentscanner">
             <span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Document Scanner
         </NavLink>
     </div>
    
  2. Implement the Document Scanner in DocumentScanner.razor: Add the following code in DocumentScanner.razor to set up the document scanner functionality:
     @page "/documentscanner"
     @inject IJSRuntime JSRuntime
        
     @if (isLoading)
     {
         <div id="loading-indicator" class="loading-indicator">
             <div class="spinner"></div>
         </div>
     }
        
     <div id="@containerId" class="container"></div>
        
     @code {
         private Boolean isLoading = true;
         private String containerId = "document_scanner";
         protected override async Task OnAfterRenderAsync(bool firstRender)
         {
             if (firstRender)
             {
                 await JSRuntime.InvokeVoidAsync("jsFunctions.initDocumentScanner", containerId);
                 isLoading = false;
                 StateHasChanged();
             }
         }
     }
    

    Explanation

    • @page "/documentscanner" sets the route for the component.
    • OnAfterRenderAsync() initializes the document scanner by calling the JavaScript function initDocumentScanner when the page loads.
  3. Reuse JavaScript Code: Copy uiConfig.js and utils.js from the .NET MAUI Blazor Hybrid App to the Blazor WebAssembly project. These files contain essential UI configuration and utility functions for the document scanner. Next, add the document scanner creation code to jsInterop.js:
     window.jsFunctions = {
         ...
         initDocumentScanner: async function (containerId) {
             if (!isInitialized) {
                 alert("Please set the license first.");
                 return;
             }
        
             try {
                 await initDocDetectModule(Dynamsoft.DDV, Dynamsoft.CVR);
        
                 const captureViewer = new Dynamsoft.DDV.CaptureViewer({
                     container: containerId,
                     uiConfig: isMobile() ? mobileCaptureViewerUiConfig : pcCaptureViewerUiConfig,
                     viewerConfig: {
                         acceptedPolygonConfidence: 60,
                         enableAutoDetect: true,
                     }
                 });
        
                 await captureViewer.play({ resolution: [1920, 1080] });
        
                 captureViewer.on("showPerspectiveViewer", () => switchViewer(0, 1, 0));
                    
                 const perspectiveViewer = new Dynamsoft.DDV.PerspectiveViewer({
                     container: containerId,
                     groupUid: captureViewer.groupUid,
                     uiConfig: isMobile() ? mobilePerspectiveUiConfig : pcPerspectiveUiConfig,
                     viewerConfig: { scrollToLatest: true }
                 });
        
                 perspectiveViewer.hide();
                 perspectiveViewer.on("backToCaptureViewer", () => {
                     switchViewer(1, 0, 0);
                     captureViewer.play();
                 });
        
                 perspectiveViewer.on("showEditViewer", () => switchViewer(0, 0, 1));
        
                 const editViewer = new Dynamsoft.DDV.EditViewer({
                     container: containerId,
                     groupUid: captureViewer.groupUid,
                     uiConfig: isMobile() ? mobileEditViewerUiConfig : pcEditViewerUiConfig
                 });
        
                 editViewer.hide();
                 editViewer.on("backToPerspectiveViewer", () => switchViewer(0, 1, 0));
        
                 const switchViewer = (c, p, e) => {
                     captureViewer.hide();
                     perspectiveViewer.hide();
                     editViewer.hide();
                     if (c) captureViewer.show();
                     else captureViewer.stop();
                     if (p) perspectiveViewer.show();
                     if (e) editViewer.show();
                 };
                    
             }
             catch (e) {
                 console.log({
                     container: containerId,
                     uiConfig: isMobile() ? mobilePerspectiveUiConfig : pcPerspectiveUiConfig,
                     viewerConfig: { scrollToLatest: true }
                 });
                 alert(e);
             }
         }
     };
    

    Explanation

    • initDocumentScanner() initializes the document scanner by creating instances of CaptureViewer, PerspectiveViewer, and EditViewer. These viewers allow users to capture images, adjust perspectives, and edit images before saving them as PDFs.
    • The switchViewer() function manages transitions between the capture, perspective, and edit viewers based on user actions.

Step 4: Run the Blazor Document PDF Viewing and Annotation Application

To run the application, press F5 in Visual Studio. This will launch the Blazor application in your default web browser, starting on the home page where you can activate the SDK by entering your Dynamsoft Capture Vision trial license key and clicking the Activate the SDK button.

  • Document Viewer: Load a PDF by clicking the add file button. You can navigate through pages, zoom, and annotate the document using various tools.

    Blazor WebAssembly document PDF viewer

  • Document Scanner: Use a connected camera to scan a document, then edit, crop, and save the scanned image as a PDF.

    Blazor WebAssembly document scanner

Source Code

https://github.com/yushulx/blazor-barcode-mrz-document-scanner