Resource Base
Table of contents
Notice: This documentation is archived. For the latest product features and documentation, please visit Dynamsoft Capture Vision Documentation.

Getting Started with Dynamsoft Document Normalizer SDK .NET Edition

In this guide, you will learn step by step on how to build a document normalization application with Dynamsoft Document Normalizer SDK using C#.

System Requirements

To find out whether your environment is supported, please read the System Requirements.

Build Your First Application

Let’s start by creating a console application which demonstrates how to use the minimum code to detect and normalize a document from an image file.

You can download the entire source code from here.

Create a New Project

Start Visual Studio or your preferred C# IDE.

Create a new C# Console Application project.

Install the NuGet Package

In the Solution Explorer, right-click on your project and select Manage NuGet Packages.

Search for and install the Dynamsoft.DotNet.DocumentNormalizer.Bundle nuget package.

If you prefer to use the offline packages, please

Download the .NET Package now and extract it into a directory of your choice.

Add the extracted .\Dynamsoft\Packages directory as a new package source

Install following packages from the added package source:

  • Dynamsoft.DotNet.DocumentNormalizer
  • Dynamsoft.DotNet.CaptureVisionRouter
  • Dynamsoft.DotNet.Core
  • Dynamsoft.DotNet.ImageProcessing
  • Dynamsoft.DotNet.License
  • Dynamsoft.DotNet.Utility

Import the Namespace

Open the Program.cs file and add the following namespaces.

using Dynamsoft.DDN;
using Dynamsoft.Core;
using Dynamsoft.CVR;
using Dynamsoft.License;

Initialize the License Key

Open the Program.cs file and add the following code inside the Main method to initialize the license for using the SDK in the application:

int errorCode = 1;
string errorMsg;
errorCode = LicenseManager.InitLicense("DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9", out errorMsg);
if (errorCode != (int)EnumErrorCode.EC_OK && errorCode != (int)EnumErrorCode.EC_LICENSE_CACHE_USED)
    Console.WriteLine("License initialization error: " + errorMsg);

The string “DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9” here is a free public trial license. Note that network connection is required for this license to work. When it expires, you can request a 30-day trial license via the Request a Trial License link.

Create a CaptureVisionRouter Instance

using (CaptureVisionRouter cvr = new CaptureVisionRouter())
{
    //code for invoking the document capturing
}

Invoke the Document Capturing

using (CaptureVisionRouter cvr = new CaptureVisionRouter())
{
    string imageFile = "[PATH-TO-THE-IMAGE-FILE]";
    CapturedResult? result = cvr.Capture(imageFile, PresetTemplate.PT_DETECT_AND_NORMALIZE_DOCUMENT);
    //code for filtering and getting document detection and normalization results
}

Please change the [PATH-TO-THE-IMAGE-FILE] to a real image file path.

Sample images are also available in the \Dynamsoft\Resources\DocumentNormalizer\Images directory within the downloaded .NET package.

Filter and Get Document Detection and Normalization Results

if (result == null)
{
    Console.WriteLine("No Result.");
}
else if(result.GetErrorCode() != 0)
{
    Console.WriteLine("Error: " + result.GetErrorCode() + ", " + result.GetErrorString());
}
else
{
    NormalizedImagesResult? normalizedImagesResult = result.GetNormalizedImagesResult();
    if (normalizedImagesResult != null)
    {
        NormalizedImageResultItem[] items = normalizedImagesResult.GetItems();
        Console.WriteLine("Detected and Normalized " + items.Length + " documents");
        foreach (NormalizedImageResultItem normalizedItem in items)
        {
            string outPath = "normalizedResult_" + Array.IndexOf(items, normalizedItem) + ".png";
            ImageManager imageManager = new ImageManager();
            var image = normalizedItem.GetImageData();
            if (image != null)
            {
                errorCode = imageManager.SaveToFile(image, outPath);
                if (errorCode == 0)
                {
                    Console.WriteLine("Document " + Array.IndexOf(items, normalizedItem) + " file: " + outPath);
                }
            }
        }
    }
}

Build and Run the Project

Save the Program.cs file and then compile and run the program using your IDE (such as Visual Studio). You will see the output message in the console like

Detected and Normalized 1 documents
Document 1 file: normalizedResult_1.png

Process Multiple Images

If, instead of processing one single image, you need to process many images at once, you can follow these steps:

These steps follow the step Create a CaptureVisionRouter Instance mentioned above.

You can download the entire source code from here.

Import the Additional Namespace.

using Dynamsoft.Utility;

Create an ImageSource as the Input

An ImageSource is required when crreating a multi-image processing application. You can either utilize ready-made image sources such as FileFetcher and DirectoryFetcher, or customize your own image source based on the base class ImageSourceAdapter.

In this sample, we will use the DirectoryFetcher to retrieve images from a local directory.

DirectoryFetcher fetcher = new DirectoryFetcher();
fetcher.SetDirectory("[THE DIRECTORY THAT HOLDS THE IMAGES]");

Please change the [THE DIRECTORY THAT HOLDS THE IMAGES] to full path of the directory holding image files.

Sample images are also available in the \Dynamsoft\Resources\DocumentNormalizer\Images directory within the downloaded .NET package.

Implement a CapturedResultReceiver as the Output Listener

Create a class MyCapturedResultReceiver to implement the CapturedResultReceiver interface, and get the barocde results in OnNormalizedImagesReceived callback function.

class MyCapturedResultReceiver : CapturedResultReceiver
{
    public override void OnNormalizedImagesReceived(NormalizedImagesResult result)
    {
        FileImageTag? tag = (FileImageTag?)result.GetOriginalImageTag();
        Console.WriteLine("File: " + tag.GetFilePath());
        if (result.GetErrorCode() != (int)EnumErrorCode.EC_OK)
        {
            Console.WriteLine("Error: " + result.GetErrorString());
        }
        else
        {
            NormalizedImagesResult? normalizedImagesResult = result.GetNormalizedImagesResult();
            if (normalizedImagesResult != null)
            {
                NormalizedImageResultItem[] items = normalizedImagesResult.GetItems();
                Console.WriteLine("Detected and Normalized " + items.Length + " documents");
                foreach (NormalizedImageResultItem normalizedItem in items)
                {
                    string outPath = "normalizedResult_" + Array.IndexOf(items, normalizedItem) + ".png";
                    ImageManager imageManager = new ImageManager();
                    var image = normalizedItem.GetImageData();
                    if (image != null)
                    {
                        errorCode = imageManager.SaveToFile(image, outPath);
                        if (errorCode == 0)
                        {
                            Console.WriteLine("Document " + Array.IndexOf(items, normalizedItem) + " file: " + outPath);
                        }
                    }
                }
            }
        }
        Console.WriteLine();
    }
}

Handle Capture Stoppage by Implementing a ImageSource State Listener

Create a class MyImageSourceStateListener to implement the IImageSourceStateListener interface, and call StopCapturing in OnImageSourceStateReceived callback function when the state is ISS_EXHAUSTED.

class MyImageSourceStateListener : IImageSourceStateListener
{
    private CaptureVisionRouter? cvr = null;
    public MyImageSourceStateListener(CaptureVisionRouter cvr)
    {
        this.cvr = cvr;
    }
    public void OnImageSourceStateReceived(EnumImageSourceState state)
    {
        if (state == EnumImageSourceState.ISS_EXHAUSTED)
        {
            if (cvr != null)
            {
                cvr.StopCapturing();
            }
        }
    }
}

Register the Input, Output Listener and ImageSource State Listener to the CaptureVisionRouter Instance

cvr.SetInput(fetcher);
CapturedResultReceiver receiver = new MyCapturedResultReceiver();
cvr.AddResultReceiver(receiver);
MyImageSourceStateListener listener = new MyImageSourceStateListener(cvr);
cvr.AddImageSourceStateListener(listener);

Start the Capturing Process

Call the method StartCapturing() to start processing all the images in the specified folder.

errorCode = cvr.StartCapturing(PresetTemplate.PT_DETECT_AND_NORMALIZE_DOCUMENT, true, out errorMsg);
if (errorCode != (int)EnumErrorCode.EC_OK)
{
    Console.WriteLine("error: " + errorMsg);
}

During the process, the callback function OnNormalizedImagesReceived() is triggered each time processing of an image is finished. After all images are processed, the listener function OnImageSourceStateReceived() will be triggered while the image source state is ISS_EXHAUSTED and the process is stopped with the method StopCapturing().

Build and Run the Project Again

Please refer to Build and Run the Project.

Version 2.2.12

    • version 2.2.12
    • Version 2.x
      • Version 2.2.10
      • Version 2.2.0
      • Version 2.0.20
      • Version 2.0.10
      • Version 2.0.0
    • Version 1.x
      • Version 1.0.20
      • Version 1.0.10
      • Version 1.0.0
    Change +