65.9K
CodeProject 正在变化。 阅读更多。
Home

如何从 Web 扫描 TIFF 和 PDF

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2009年11月27日

CPOL

8分钟阅读

viewsIcon

48113

有些事情,例如扫描文档,仅凭 HTML 和 Javascript 等浏览器技术无法完成。因此,我们开发了一个易于使用的 ActiveX Twain 控件,它只需要基本的 Javascript 知识即可有效使用。

越来越多的公司正在转向基于 Web 的解决方案,您能责怪他们吗? Web 提供了与其他系统的轻松集成,以及所有最终用户都可以从中进行升级的单一入口点。构建 Web 应用程序的一个问题是,有些事情,例如扫描文档,仅凭 HTML 和 Javascript 等浏览器技术无法完成,您必须使用 ActiveX 等技术。

ActiveX 是一个棘手的野兽,在任何特定版本的 Internet Explorer 中运行的要求都是一个不断变化的目标。因此,我们开发了一个易于使用的 ActiveX Twain 控件,它只需要基本的 Javascript 知识即可有效使用。您只需要在您的网站上粘贴一个对象标签,连接几个事件,然后运行几个简单的命令。在本文中,您将完成以下任务

让我们开始吧。

安装和许可 DotTwain

在开始之前,您必须先下载并安装 Atalasoft DotTwain Toolkit。安装完成后,我们的激活向导将启动,您应该请求 DotTwain 的 30 天评估版。下图演示了该过程的每个步骤。请注意,尽管版本号可能已更改,但步骤将保持不变。

  1. 下载并安装最新版本的DotTwain Toolkit
  2. 安装程序完成后,Toolkit Activation Wizard 将自动启动。单击“下一步”开始。

    image001.jpg

  3. 选择“请求 30 天评估版”并单击“下一步”。

    image002.jpg

  4. 确保在“要评估的工具包”下选择了“DotTwain”。如果您想探索我们工具包的其他方面,也可以安全地选择其他选项。选择 DotTwain 后,输入您的 Atalasoft.com 帐户名和密码,然后单击“下一步”。

    image003.jpg

  5. 最后,单击“完成”退出激活向导。

    image004.jpg

将扫描 ActiveX 控件放在页面上并进行初始化

现在您已经安装并许可了 DotTwain,您可以继续开始构建您的 Twain ActiveX 扫描解决方案。为此,首先需要创建一个 Web 站点项目并将必要的 cab 文件放在该位置。为此:

  1. 在 Visual Studio 中创建一个新的空目录 Web 站点。

    image005.jpg

  2. Atalasoft.DotTwain.Controls.cab 复制到您的 Web 站点目录,该文件可以在 DotTwain 安装子目录的“\bin\2.0\x86”中找到。

    image006.jpg

  3. 将 DotTwain ActiveX 控件对象标签添加到您的 html 中。
    <object id="ScanningControl" 
               name="ScanningControl" 
            classid="clsid:7D7102FE-6517-441c-AE7A-3DA4085B1E73"
            codebase="Atalasoft.DotTwain.Controls.cab#version=1,0,0,0" 
            height="0" 
            width="0">
    </object>
  4. 最后,将一个调用控件 Initialize() 函数的命令添加到页面的 onload 属性中。这将确保每次加载页面时都会初始化控件。
    <body onload="return
    document.ScanningControl.Initialize();">

此时,我们已经有了基础,但还没有什么可以真正工作的。在继续之前,有必要创建一个方法来保存扫描后服务器上的图像。

创建一个服务来保存您的扫描图像

接下来,有必要创建一个小型服务来保存您上传的文件。

  1. 在您的 Web 站点目录中创建一个 Images 子文件夹。扫描文件将存储在此处。
  2. 创建一个名为 FileStorage.aspx 的新 Web 窗体。此 Web 窗体将作为图像上传服务,处理扫描图像的上传和后续下载。

    image007.jpg

  3. 最后,将以下代码添加到您的 FileStorage.cs 后置代码中。它既可以将传入的文件保存到您之前创建的 images 文件夹,又可以在请求 GetFile 参数时从该文件夹检索图像。
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            string fileStoragePath = 
                Path.Combine(Request.PhysicalApplicationPath, "Images");
     
            //If the GetFile parameter is present return the requested file.
            string requestedFilename = Request.Params["GetFile"];
            if (requestedFilename != null)
            {
                string safeFilename = Path.GetFileName(requestedFilename);
                string fullFilePath = Path.Combine(fileStoragePath,
                                        safeFilename);
     
                if (File.Exists(fullFilePath))
                {
                    Response.WriteFile(fullFilePath);
                }
            }
     
            //If the request contains files, save them.
            if (Request.Files.Count > 0)
            {
                foreach (String field in Request.Files.AllKeys)
                {
                    HttpPostedFile file = Request.Files[field];
                    string safeFilename = Path.GetFileName(file.FileName);
                    string fullFilePath = 
                            Path.Combine(fileStoragePath, safeFilename);
     
                    file.SaveAs(fullFilePath);
                }
            }
        }
        catch (Exception ex)
        {
            Debug.Write(ex.ToString());
        }
    }

现在我们已经有了保存和检索图像的方法,我们可以继续设置我们的 ActiveX 控件。

通过 Javascript 调用控件进行扫描和上传

接下来,有必要使用 Javascript 设置控件,以便可以使用它。我们的界面基于 Javascript 事件模型,该模型允许您花费少量精力同时进行扫描和上传图像。

  1. 添加一个扫描按钮和 Javascript。

    首先,在您的表单中添加一个输入按钮,该按钮在单击时会调用 Scan()。

    <input type="button" value="Scan" onclick="Scan()" />

    然后我们必须定义我们的 Scan() 函数。在这里,我们创建一个新的扫描批处理过程,并将其传递给控件的 ScanBatch 方法。请注意,由于我们还没有构建选择扫描仪的方法,因此 scanningDevice 变量目前将始终为 null。

    <script language="javascript" type="text/javascript">
    scanningDevice = null;
     
    function Scan() {
      if (scanningDevice) {
        var batch = document.ScanningControl.CreateNewBatch(scanningDevice);
        document.ScanningControl.BatchScan(batch);
      }
    }
    </script>
  2. 添加一个设备选择组合框和 Javascript。

    对于此步骤,我们首先需要创建一个 select 标签来包含我们的扫描仪选项。这将是一个下拉框,其中包含系统中找到的所有 Twain 设备。

    Device: <select id="ScannerList" 
             onchange="return SelectedScannerChanged();"></select>

    然后,我们必须定义一系列简单的 Javascript 函数来管理我们的新下拉框。

    • GetSelectedScanner() 检索下拉框中当前选定的扫描仪的文本名称。
    • SelectedScannerChanged() 设计用于在更改选定扫描仪时调用,以便 selectedDevice 变量始终包含当前选定扫描仪的可查询表示。
    • FillScannerSelect() 接受一个可用扫描仪的数组,并将每个扫描仪添加到 'ScannerList' select 框中。完成后,它会调用 SelectedScannerChanged() 以确保 scanningDevice 变量的状态正确。
    <script language="javascript" type="text/javascript">
     
    function GetSelectedScanner() {
      var formatSelect = document.getElementById("ScannerList");
      return formatSelect.options[formatSelect.selectedIndex].value;
    }
     
    function SelectedScannerChanged() {
      var scannerName = GetSelectedScanner();
      scanningDevice = document.ScanningControl.GetDevice(scannerName);
    }
     
    function FillScannerSelect(scannerArray) {
      var scannerSelect = document.getElementById("ScannerList");
      scannerSelect.length = 0;
      if (scannerArray.length > 0) {
          for (var i = 0; i < scannerArray.length; i++) {
              scannerSelect.add(new Option(scannerArray[i], scannerArray[i]));
          }
      }
      scannerSelect.selectedIndex = 0;
      SelectedScannerChanged();
    }
     
    </script>
  3. 设置控件初始化

    我们现在已经有了构建扫描仪列表所需的所有内容,但您会注意到它目前从未被调用过。最合适的地方是在 ControlInitializationComplete 事件中。当调用此事件时,您将知道 Twain 已准备好使用并且许可已成功完成。在此之前,除了 Initialize() 之外,调用控件的任何函数都不安全。

    <script for="ScanningControl" event="ControlInitializationComplete(args)" 
        language="jscript" type="text/jscript">
      if (args.TwainIsAvailable == true) {
        var scannerArray = document.ScanningControl.GetAvailableDevices();
        FillScannerSelect(scannerArray);
      } 
    </script>

    添加 ControlInitializationStarting 的存根也是一个好主意,因为一旦您拥有 DotTwain 的完整版本,许可就会在这里进行。

    <script for="ScanningControl" event="ControlInitializationStarting(args)" 
        language="jscript" type="text/jscript">
      //Note: To deploy it is necessary to set the url to your license here.
      //args.LicenseUrl = "http://hostname/Atalasoft.DotTwain.lic";
    </script>
  4. 设置文件传输和显示

    现在我们的控件正在积极工作,我们必须添加上传功能。首先,让我们添加一个 div 来放置我们新扫描的图像。

    <div id="ScannedImages"></div>

    接下来,我们必须定义一系列函数,以便更容易地管理从此 div 添加和删除图像。

    <script language="javascript" type="text/javascript">
    function GetFileStorageUrl() {    
      var href = window.location.href;
      var baseUrl = href.substring(0, href.lastIndexOf("/"));
      var urlUploadLocation = baseUrl + "/FileStorage.aspx";
      return urlUploadLocation;
    }
     
    function GetFileDownloadUrl(filename) {    
      var fileStorageUrl = GetFileStorageUrl();
      var fullUrl = fileStorageUrl + "?GetFile=" + filename;
      return fullUrl;
    }
     
    function AddImageToScannedImages(url) {
         var uploadedImagesDiv = document.getElementById("ScannedImages");
         var aTag = document.createElement('A');
         aTag.setAttribute("href", url);
         aTag.innerText = "Image<br />";
         uploadedImagesDiv.appendChild(aTag);
    }
    </script>

    然后我们必须添加 TransferStarting 和 TransferComplete 事件的挂钩。 **在调用 TransferStarting 时,您必须指定扫描图像将上传到的 URL。** 如果未指定 args.TransferArgs.Uri,控件将引发错误。

    <script for="ScanningControl" event="TransferStarting(args)" language="jscript" 
        type="text/jscript">
        args.TransferArgs.Uri = GetFileStorageUrl();
    </script>

    当调用 TransferComplete 时,我们知道图像已成功传输,因此我们可以安全地将其添加到我们的 'ScannedImages' div 中。

    <script for="ScanningControl" event="TransferComplete(args)" language="jscript" 
        type="text/jscript">
        var imageUrl = GetFileDownloadUrl(args.TransferArgs.Filename);
        AddImageToScannedImages(imageUrl);
    </script>
  5. 记录错误

    最后,为了记录可能发生的任何错误,有必要挂接到控件的 Error 事件。

    <script for="ScanningControl" event="Error(args)" language="jscript" 
        type="text/jscript">
        var message = "An error occurred. ";
        if (args.Exception) message += args.Exception.ToString();
        alert( message );
    </script>

此时,您应该有一个可以上传默认 PNG 格式的扫描件并在页面上显示这些图像链接的工作页面。但是,还需要一些额外的工作才能选择 Tiff 和 Pdf 等图像格式。

奖励:添加一个选择控件来选择格式

在上述基础设施到位后,添加格式选择支持现在是微不足道的。涉及的大部分工作是创建和管理可用格式的选择框。

  1. 为文件格式添加组合框

    正如上面讨论的,我们必须首先创建一个 select 标签,用于显示当前选定扫描仪的可用格式。

    File Format: <select id="ImageFormat"> </select>

    接下来,与 'ScannerList' select 框一样,我们必须定义一些简单的函数来轻松操作这个 select 框。

    • GetSelectedImageFormat() 返回 ImageFormat select 框中当前选定的值。
    • FillImageFormatSelect() 接受一个文件格式数组,并将该数组的内容设置为 'ImageFormat' select 框中的可用选项集。
    <script language="javascript" type="text/javascript">
    function GetSelectedImageFormat() {
      var formatSelect = document.getElementById("ImageFormat");
      return formatSelect.options[formatSelect.selectedIndex].value;
    }
    function FillFileFormatSelect(formatArray) {
         var formatSelect = document.getElementById("ImageFormat"); 
         formatSelect.length = 0;
         if (formatArray.length > 0) {
          for (var i = 0; i < formatArray.length; i++) {
              formatSelect.add(new Option(formatArray[i], formatArray[i]));
          }
      }
      formatSelect.selectedIndex = 0;
    }
    </script>
  2. 在选择设备时在组合框中列出特定于扫描仪的文件格式

    因为我们上面创建了 FillImageFormatSelect 函数,所以这可以通过在 SelectedScannerChanged 事件中添加两行来实现。下面的两行粗体代码通过可查询设备对象的 SupportedImageFormats 属性获取支持的图像格式数组,并将该数组传递给 FillImageFormatSelect() 函数。

    <script language="javascript" type="text/javascript">
     
    function GetSelectedScanner() {
      var formatSelect = document.getElementById("ScannerList");
      return formatSelect.options[formatSelect.selectedIndex].value;
    }
     
    function SelectedScannerChanged() {
      var scannerName = GetSelectedScanner();
      scanningDevice = document.ScanningControl.GetDevice(scannerName);
    }
     
    function FillScannerSelect(scannerArray) {
      var scannerSelect = document.getElementById("ScannerList");
      scannerSelect.length = 0;
      if (scannerArray.length > 0) {
          for (var i = 0; i < scannerArray.length; i++) {
              scannerSelect.add(new Option(scannerArray[i], scannerArray[i]));
          }
      }
      scannerSelect.selectedIndex = 0;
      SelectedScannerChanged();
    }
     
    </script>
  3. 在扫描前设置选定的文件格式

    最后,我们必须在 Scan() 函数中添加一行代码,以在将批次提交处理之前设置其 Image 格式。这一行(如下粗体显示)只是将批对象设置为 ImageFormat select 框中设置的文本。

    <script for="ScanningControl" event="ControlInitializationComplete(args)" 
        language="jscript" type="text/jscript">
      if (args.TwainIsAvailable == true) {
        var scannerArray = document.ScanningControl.GetAvailableDevices();
        FillScannerSelect(scannerArray);
      } 
    </script>

结论

恭喜您,您现在拥有一个功能齐全的 Twain 扫描网页。

本文所述的功能只是 DotTwain ActiveX 控件可能实现的最小功能。有关更多信息,请参阅 DotTwain 帮助文件中的“ActiveX 控件概述”和“ActiveX 控件 API 参考”部分,其中记录了我们控件的完整功能。

image008.jpg

有关带有注释和附加功能的更详细示例,请查看我们的 WebScanning 演示,这些演示在开始菜单中 DotTwain 下的“演示”部分提供。

image009.jpg

如果您想在您的网站中使用 DotTwain,但需要评估其更多功能,请通过请求自定义概念验证告知我们。

© . All rights reserved.