Twain.Wia.Sane.Scanner 2.0.0

dotnet add package Twain.Wia.Sane.Scanner --version 2.0.0
                    
NuGet\Install-Package Twain.Wia.Sane.Scanner -Version 2.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Twain.Wia.Sane.Scanner" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Twain.Wia.Sane.Scanner" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Twain.Wia.Sane.Scanner" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Twain.Wia.Sane.Scanner --version 2.0.0
                    
#r "nuget: Twain.Wia.Sane.Scanner, 2.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=Twain.Wia.Sane.Scanner&version=2.0.0
                    
Install Twain.Wia.Sane.Scanner as a Cake Addin
#tool nuget:?package=Twain.Wia.Sane.Scanner&version=2.0.0
                    
Install Twain.Wia.Sane.Scanner as a Cake Tool

.NET Document Scanner for TWAIN, WIA, SANE, ICA, and eSCL

This .NET package provides a wrapper for calling the Dynamic Web TWAIN Service REST API. It enables developers to create desktop or cross-platform applications to scan and digitize documents using:

  • TWAIN (32-bit / 64-bit)
  • WIA (Windows Image Acquisition)
  • SANE (Linux)
  • ICA (macOS)
  • eSCL (AirScan / Mopria)

Demo Video

https://github.com/yushulx/dotnet-twain-wia-sane-scanner/assets/2202306/1046f5f4-2009-4905-95b5-c750195df715


โš™๏ธ Prerequisites

โœ… Install Dynamic Web TWAIN Service

๐Ÿ”‘ Get a License

Request a free trial license.


๐Ÿงฉ Configuration

After installation, open http://127.0.0.1:18625/ in your browser to configure the host and port settings.

By default, the service is bound to 127.0.0.1. To access it across the LAN, change the host to your local IP (e.g., 192.168.8.72).

dynamic-web-twain-service-config


๐Ÿ“ก REST API Endpoints

https://www.dynamsoft.com/web-twain/docs/info/api/restful.html

๐Ÿงช Quick Start

Replace the license key in the following code and run it in a .NET project:

using Newtonsoft.Json;
using Twain.Wia.Sane.Scanner;

public class Program
{
    private static string licenseKey = "LICENSE-KEY";
    private static ScannerController scannerController = new ScannerController();
    private static List<Dictionary<string, object>> devices = new List<Dictionary<string, object>>();
    private static string host = "http://127.0.0.1:18622";
    private static string questions = @"
Please select an operation:
1. Get scanners
2. Acquire documents by scanner index
3. Quit
";

    public static async Task Main()
    {
        var info = await scannerController.GetServerInfo(host);
        Console.WriteLine($"Server info: {info}");
        await AskQuestion();
    }

    private static async Task<int> AskQuestion()
    {
        while (true)
        {
            Console.WriteLine(".............................................");
            Console.WriteLine(questions);
            string? answer = Console.ReadLine();

            if (string.IsNullOrEmpty(answer))
            {
                continue;
            }

            if (answer == "3")
            {
                break;
            }
            else if (answer == "1")
            {
                var scannerInfo = await scannerController.GetDevices(host, ScannerType.TWAINSCANNER | ScannerType.TWAINX64SCANNER);
                devices.Clear();

                try { 
                    var scanners = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(scannerInfo);
                    for (int i = 0; i < scanners.Count; i++)
                    {
                        var scanner = scanners[i];
                        devices.Add(scanner);
                        Console.WriteLine($"\nIndex: {i}, Name: {scanner["name"]}");
                    }
                } catch (Exception ex) { 
                   Console.WriteLine($"Error: {ex.Message}");
                }
                
            }
            else if (answer == "2")
            {
                if (devices.Count == 0)
                {
                    Console.WriteLine("Please get scanners first!\n");
                    continue;
                }

                Console.Write($"\nSelect an index (<= {devices.Count - 1}): ");
                int index;
                if (!int.TryParse(Console.ReadLine(), out index))
                {
                    Console.WriteLine("Invalid input. Please enter a number.");
                    continue;
                }

                if (index < 0 || index >= devices.Count)
                {
                    Console.WriteLine("It is out of range.");
                    continue;
                }

                var parameters = new Dictionary<string, object>
                {
                    {"license", licenseKey},
                    {"device", devices[index]["device"]},
                    {"autoRun", true}
                };

                parameters["config"] = new Dictionary<string, object>
                {
                    {"IfShowUI", false},
                    {"PixelType", 2},
                    {"Resolution", 200},
                    {"IfFeederEnabled", false},
                    {"IfDuplexEnabled", false}
                };

                var jobInfo = await scannerController.CreateJob(host, parameters);
                string jobId = "";
                try
                {
                    var job = JsonConvert.DeserializeObject<Dictionary<string, object>>(jobInfo);
                    jobId = (string)job["jobuid"];

                    if (string.IsNullOrEmpty(jobId))
                    {
                        Console.WriteLine("Failed to create job.");
                        continue;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error: {ex.Message}");
                    continue;
                }

                var images = await scannerController.GetImageFiles(host, jobId, "./");
                for (int i = 0; i < images.Count; i++)
                {
                    Console.WriteLine($"Image {i}: {images[i]}");
                }

                await scannerController.DeleteJob(host, jobId);
            }
            else
            {
                continue;
            }
        }
        return 0;
    }
}

๐Ÿ“ Examples


๐Ÿงฉ API Reference

๐ŸŽ›๏ธ Scanner APIs

  • GetDevices(string host, int? scannerType = null)
  • CreateJob(string host, Dictionary<string, object> parameters)
  • CheckJob(string host, string jobId)
  • UpdateJob(string host, string jobId, Dictionary<string, object> parameters)
  • DeleteJob(string host, string jobId)
  • GetScannerCapabilities(string host, string jobId)
  • GetImageInfo(string host, string jobId)

๐Ÿ“ธ Image APIs

  • GetImageFile(string host, string jobId, string directory)
  • GetImageFiles(string host, string jobId, string directory)
  • GetImageStream(string host, string jobId)
  • GetImageStreams(string host, string jobId)

๐Ÿ“„ Document APIs

  • CreateDocument(string host, Dictionary<string, object> parameters)
  • GetDocumentInfo(string host, string docId)
  • DeleteDocument(string host, string docId)
  • GetDocumentFile(string host, string docId, string directory)
  • GetDocumentStream(string host, string docId)
  • InsertPage(string host, string docId, Dictionary<string, object> parameters)
  • DeletePage(string host, string docId, string pageId)

๐Ÿ“ฆ Build the NuGet Package

dotnet build --configuration Release
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2.0.0 153 11 days ago
1.2.0 429 8 months ago
1.1.0 603 10/25/2023
1.0.1 200 10/10/2023
1.0.0 183 10/10/2023

- Added new methods for returning HTTP response messages.