Simple Uses of Captiva’s Multi Module – Part 2

In this post I demonstrate a simple CaptureFlow script to split pages into documents when a Patch 3 separator sheet is encountered. Refer to the previous post for details regarding the desired Patch 3 behavior. For context, the CaptureFlow snippet is repeated here.

The Multi module can be used to modify the Captiva node tree and convert pages into documents by “splitting” the list of page nodes into a list of documents with single pages. Perhaps the easiest way to understand this behavior and the desired outcome is to examine the graphic below.  When the Patch 3 sheet is encountered in the node tree on the left, it is deleted and a level 1 node is inserted before every following level 0 node, until another level 1 node is encountered or the end of the batch.


To create a CaptureFlow script in Captiva Designer, click the Multi module step that will implement this function (ProcessPatch3 in my CaptureFlow depicted above), and choose Scripting… from the drop down menu. The CaptureFlow scripting editor will open. The following VB code implements the required functionality.

Imports System
Imports Emc.InputAccel.CaptureFlow

Public Partial Class MultiTest

' #1 – execute before module is triggered
Public Shared Sub ProcessPatch3_Prepare (node As IBatchNodeData)
  Dim docs As IBatchNodeData()
  Dim pages As IBatchNodeData()
  Dim patchcode As String = ""
  Dim imgProc As IBatchNodeData
  Dim has_Patch_3 As Boolean = False

  ' define Multi constants
  Dim IAMULTI_DELETE As Int16 = 16
  Dim IAMULTI_READY As Int16 = 8

  On Error Resume Next

  ' #2 - get collection of all documents in batch
  docs = node.GetDescendantNodes(1)
  For Each doc As IBatchNodeData In docs

    ' #3 - get collection of pages from each document
    pages = doc.GetDescendantNodes(0)

    ' #4 - evaluate each page
    For Each page As IBatchNodeData In pages

      ' #5 – get patch code from Image Processor step
      imgProc = page.GetStepNode("ImageProcessor")
      patchcode = imgProc.ReadString("Patchcode")

      ' #6 – if this page is patch code, set flag and delete
      ' this page
      If patchcode.Equals("3") Then
        has_Patch_3 = True

      ' #7 – otherwise process it accordingly
        If has_Patch_3 = True Then
        End If
      End If
    has_Patch_3 = False
End Sub
End Class

Here is how this code works:

  1. The CaptureFlow script editor automatically creates the _Prepare() and _Finish() methods for your module. Because I want to set all of the trigger values before the Multi module is executed, I implement this logic in the _Prepare() method.
  2. Get all of the documents in the batch into a collection.  This is accomplished by passing 1 as the level parameter to the GetDescendantNodes() method.  The node object here is essentially the entire Captiva node tree as it is being sent to the RemoveEmptyDocs step.
  3. For each document in the collection, get a collection of its pages.  This code uses the same GetDescendantNodes() method as step 2, but now the “node” it is operating on is a document retrieved in step 2, and the level parameter is 0 (pages).
  4. For each page in the collection, evaluate each page.
  5. Reach back to the ImageProcessing step for each page to retrieve the Patchcode value for this page.  Patchcode is a standard level 0 IA value.
  6. If patchcode equals 3, I have found a Patch 3 sheet. Set the global variable, has_Patch_3 = true and delete this page.
  7. If patchcode is empty or some other value, then check to see if a patch code has been encountered in this document (i.e., has_Patch_3 = true). If so, split this page into its own document using the Ready trigger value 1. Otherwise, the page gets the default Ready value of 8.


These past couple of posts (0,1) have demonstrated some simple uses of the Captiva Multi module.  In particular, they have demonstrated how to manipulate the Captiva node tree to delete unwanted pages and documents, or to restructure the node tree based on patch codes.  The essence of both implementations, that is using IA Value assignments and CaptureFlow scripting, is the same:  assign each page’s Multi Ready trigger the no-op value (8), and then change it accordingly as conditions dictate.  The primary difference between the IA Value assignment and the CaptureFlow scripting approaches is that the CaptureFlow script is able to persist the state of the patch code while examining the page nodes of a document.  It uses this persisted state to determine whether or not to “split” the node into a document or not.  This type of persistence is not possible using IA Value assignment.

If you have other cool examples of using Captiva’s Multi module I’d like to hear about them.

Simple Uses of Captiva’s Multi Module – Part 1

In this post I demonstrate how to delete selected pages and documents from a Captiva batch using the Multi module and IA Value assignments. Refer to the previous post for details regarding the requirements for removing pages and documents. For context, the CaptureFlow snippet is repeated here.


Removing Divider Sheets

To remove all of the divider sheets in a batch, ensure the Multi module that implements this task (RemoveDividers in my CaptureFlow) is triggered at the Batch level. Then set the following IA Values before the module is triggered (location A on the diagram):

RemoveDividers:0.Ready = 8
RemoveDividers:0.Ready = 16 when ToUpper(ImageProcessor:0.Barcode0_Text) = “DIVIDER”

This has the effect that for every page, the Multi module is set to process the page normally (i.e., Ready state 8), unless it contains a barcode that reads “DIVIDER”. If a divider sheet is recognized in this way, the Ready trigger is set to 16 for that page. This structure of IA assignments is necessary because the simple IA assignment language does not contain an if-then-else construct. Also notice that although the Multi module triggers at the Batch level (7), I am setting IA values at the Page level (0). This has the desired effect of removing all of the divider sheets from the batch.

Removing Blank Pages

Removing blank pages from the batch is similar to removing the divider sheets. Prior to executing the instance of the Multi module (RemoveBlankPages in my CaptureFlow), set the following IA Values (location B on the diagram):

RemoveBlankPages:0.Ready = 8
RemoveBlankPages:0.Ready = 16 when ( (ScanPlus:0.BlankPage <> 0) OR (ImageProcessor:0.BlankPage = 1) )

Blank pages can be detected in two places: by the scanner, or by the Image Processor module. A non-blank page receives a value of 0 (zero) from ScanPlus and a value of 1 from the Image Processor. So, if either of these conditions is not true, set Multi’s Ready trigger to the delete value (16). Notice again that IA Values are set at the Page level, even though the Multi module is triggered at the Batch level. This has the desired effect of removing all of the blank pages from the batch.

Removing Empty Documents

Removing empty documents from the batch follows the same pattern as the previous two examples. The only difference is the level at which the Ready trigger is set and the condition used to set the trigger. These IA Values are set at location C in the diagram; the Multi module is named RemoveEmptyDocs in my CaptureFlow.

RemoveEmptyDocs:1.Ready = 8
RemoveEmptyDocs:1.Ready = 16 when (_Node:1.NumChildrenAtL0 = 0)

Notice here that I set the Ready trigger at level 1 (document) to delete the document if it does not have any children at level 0 (page).
In the next post, I will demonstrate how to process the Patch 3 separator sheets such that all pages following it are processed as individual documents. This implementation will utilize some simple CaptureFlow scripting.

Simple Uses of Captiva’s Multi Module – Part 0

In this series of posts I will examine some simple uses of the Captiva Multi module.  Specifically, I will demonstrate how use Multi to accomplish the following tasks:

  • Remove dividers sheets from batch – dividers are used by scan operators to help them organize and manage batch content, but are not part of the final batch. Dividers consist of colored pages with the work “DIVIDER” printed on them in English, and as a Code39 barcode.
  • Remove blank pages from batch – blank pages can occur organically in scanned document, or as a result of double-sided scanning of a single-sided page.
  • Process Kodak Patch 3 separators sheets in batch – when a Patch 3 separator sheet is encountered, it indicates that every following page is to be split into a separate document until another Patch 3 sheet is encountered, or the end of the document is encountered.
  • Remove blank documents from batch – due to the actions of any of the above tasks, it is possible to create empty documents in the Captiva node tree (i.e., a document with no pages).

Some of these tasks, like removing blank pages, can be accomplished by the scanner/ScanPlus at scan-time. However, these tasks can also be accomplished using the Captiva Multi module and some simple scripting. This is the way I chose to implement them due to their location in my CaptureFlow (they are contained in a rescan “loop”, so to speak, and can be executed more than once in a single process). Here is a snippet of my CaptureFlow where I implement these tasks.


As the name might imply, the Multi module can do multiple things: it can insert and delete nodes from the Captiva node tree; change the trigger level of tasks; delete batches when they are completed; and emit a beep when a module completes its work. The Multi module is fairly unique among Captiva modules in that it does not have a user interface, and can only be run as a service. The only way to interact with the module is to set a trigger IA value named Ready. The following table lists available values for the Ready trigger, their constant names, and their purpose.

Constant Name Value Purpose
IAMULTI_READY 8 No op. Multi holds this node until it finishes processing the entire batch and releases it unchanged.
IAMULTI_DELETE 16 Deletes the specified node (e.g., page, document).
IAMULTI_BEEP 32 Sounds a beep on the Multi machine after the specified module finishes processing.
IAMULTI_PARENT 64 Performs the indicated operation at the trigger level.
IAMULTI_SPLIT_LEVELn [1..6] Inserts a level n node before a level n-1 node.

The Ready trigger can be set using IA value assignment in the CaptureFlow, or using scripting before the Multi module is triggered. This series of blog posts will examine both approaches for using Multi. In the next post, I will examine removing divider pages, blank pages, and empty documents using IA value assignment in Captiva Designer.

You can also find examples using the Multi module in the Sample Captiva Designer project distributed with Captiva 7.

%d bloggers like this: