Click here to Skip to main content
11,639,861 members (60,088 online)
Click here to Skip to main content

The Paperless Desktop

, 5 Apr 2007 320K 6.3K 308
Rate this:
Please Sign up or sign in to vote.
How to perform scanning, rearranging, OCR and Outlook export of documents for a paperless future - or at least a tidy desktop.

Sample screenshot

Introduction

After playing around with Microsoft's Document Imaging Library (MODI) in OCR with Microsoft Office, I decided to add some features to the primary MODI application like scanning, multi TIFF rearrangement and Outlook export. The Outlook export enables you to organize your documents by email folders. Since tools like LookOut, this might be faster than the walk to the good old file cabinet.

Before reading, please note

  • You need Office 2003 or Office 2007 to run the application!
  • For Office 2007 support see the article OCR with Microsoft Office.
  • Office XP does not contain MODI and there is no way to change that!
  • For email export, you need MS Outlook 2003 or MS Outlook 2007!

The Application

The application looks very similar to the well known MS Imaging Viewer. The most important difference is the email export to offer a comfortable document storage. From the technical point of view, the application is based on three technologies: MODI, TWAIN and Outlook-Interop (for each of these topics, there is a link at the end of the article which can be used as a tutorial, therefore I won't describe specific details of these techniques). Their integration needed some changes and enhancements and this is what the article is about.

Sample screenshot

TWAIN Scanning support

First of all, I chose TWAIN support instead of the modern WIA standard because I own a scanner that only supports TWAIN. Based on the very well done code from the Scanning via TWAIN article, I created the TwainControl to encapsulate the scanning functionality. The interaction with the control is done with three methods and one event.

Init and Release

twainControl1.Init(this.Handle);
twainControl1.Release();

Device Selection

The TWAIN library offers a device selection dialog.

Sample screenshot

This dialog can be shown by calling the following method:

twainControl1.SelectDevice();

Starting the scanning process

The start method has two parameters, bool UI and bool modal. With UI = false, you can start the process without the scanner's configuration dialog. The modal flag controls the modal status of the scan dialog.

twainControl1.StartScanning(UI, modal);

Finishing the scanning process

After the control has proceeded scanning, a FinishScanning event is fired. The main application is registered as a listener.

private void twainControl1_FinishScanning(object sender,
        Util.TwainLib.FinishScanningEventArgs e)
{
    if (e.scanned)
    {
        ArrayList images = twainControl1.PopImages();
        AppendScannedImages(images);
        SaveFile();
    }
}

This is the point where integration comes in. The PopImages method writes all scanned pages (if you have a multi page scanner device) into an image array. Afterwards, these images are appended to the MODI document.

Using the scanner button

If you want to open the application by pressing the scanner hardware button, you can add the application path to the Registry. The Registry key in HKEY_LOCAL_MACHINE is Software\Microsoft\Windows\CurrentVersion\StillImage\Registered Applications.

The key value should be:

[Path\]MartinsPaperlessDesktop.exe /StiDevice:%1 /StiEvent:%2

Handling Multi-TIFF files

The first version included self written TIFF handling code (which was not making me happy). By integrating the MODI library, handling multi-TIFF files gets really simple and fast.

Appending Pages

One valuable feature is the 'append'-function which appends pages to a multi-TIFF document. In case that your scanner device does only support single page scanning, this might be helpful.

private void AppendImage(string source)
{
    if (_MODIDocument == null) return;
    try
    {
        MODI.Document document = new MODI.Document();
        document.Create(source);
        _changed = true;
        // iterate through all image pages of the source document
        for (int i = 0; i < document.Images.Count; i++)
        {
            _MODIDocument.Images.Add(document.Images[i],null);
        }
    }
    catch(Exception ee)
    {
        MessageBox.Show(ee.Message);
        SetImage("",false);
    }
}

Rearranging Pages

If you got mixed up during the scanning process, you can move single pages within the document to get the order you want.

private void MoveImage(int pageNumber, bool up)
{
    if (_MODIDocument == null) return;
    MODI.Image img = (MODI.Image) _MODIDocument.Images[pageNumber];
    if (up)
    {
        if (pageNumber-1 >= 0)
        {
            MODI.Image prevImg = 
               (MODI.Image) _MODIDocument.Images[pageNumber-1];
            // the add methode needs the "beforeImage" as second argument
            _MODIDocument.Images.Add(img,prevImg);
            MODI.Image removeImg = 
               (MODI.Image) _MODIDocument.Images[pageNumber+1]; 
            _MODIDocument.Images.Remove(removeImg);
            axMiDocView1.PageNum = pageNumber-1;
        }
    }
    else
    {
        if (pageNumber+1 < axMiDocView1.NumPages)
        {
            MODI.Image nextImg = null;
            if (pageNumber+2 < _MODIDocument.Images.Count)
            {
                nextImg = 
                  (MODI.Image) _MODIDocument.Images[pageNumber+2]; 
            }
            // if the second argument is NULL, 
            //the page is appended at the end of the image
            _MODIDocument.Images.Add(img,nextImg);
            MODI.Image removeImg = 
               (MODI.Image) _MODIDocument.Images[pageNumber]; 
            _MODIDocument.Images.Remove(removeImg);
            axMiDocView1.PageNum = pageNumber+1;
        }
    }
    // this action causes a change notification
    _changed = true;
    ShowStatus();
}

OCR and Layout Processing

One primary goal of the layout processing was to keep the original document layout alive. The OCR comes from the MODI.Document.OCR() method. I used the document model from Document Processing Part II to get a better layout serialization than provided by MODI. Since we will export the document's text to an HTML based email, a very trivial HTML converting is done.

private string GetDocumentText()
{    
    Model.Document doc = Model.Document.CreateByMODI(_MODIDocument);

    string c = doc.GetText();
        
    // very trivial converting to HTML
    c = c.Replace("\r\n","<\br\>");
    return c;
}

MS Outlook Export

Now, the work is all done and exporting is straightforward coding. The source is placed in the DocumentMailer class. The constructor method opens a connection to MS Outlook.

private Microsoft.Office.Interop.Outlook.Application oApp;
private Microsoft.Office.Interop.Outlook._NameSpace oNameSpace;
private Microsoft.Office.Interop.Outlook.MAPIFolder oOutboxFolder; 

public DocumentMailer()  
{      
    oApp = new Outlook.Application();      
    oNameSpace= oApp.GetNamespace("MAPI");      
    oNameSpace.Logon(null,null,true,true);  
    oOutboxFolder = 
       oNameSpace.GetDefaultFolder(OlDefaultFolders.olFolderOutbox);
}

With an opened Outlook connection, the AddToOutBox method does all the work.

Outlook._MailItem oMailItem = 
    (Outlook._MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
oMailItem.To = toValue;   
oMailItem.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
oMailItem.Subject = subjectValue;      
oMailItem.HTMLBody = bodyValue;     
oMailItem.SaveSentMessageFolder = oOutboxFolder;

//.. attachments

oMailItem.Save();  
oMailItem.Display(null);

E-Mail Configuration

To save us from selecting our personal settings each time again, I added a small configuration class. The code is placed in an instance of Configuration which is loaded during initialization.

Sample screenshot

To have a short look at serialization and deserialization, here is the code for loading:

public static Configuration LoadFromFile(string path)
{
    IFormatter formatter = new BinaryFormatter();
    Stream streamS = 
      new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
    object o = formatter.Deserialize(streamS);
    Configuration solution = (Configuration) o;
    streamS.Close();
    return solution ;
}

..and for saving as well:

public bool SaveToFile(string path)
{
    IFormatter formatter = new BinaryFormatter();
    Stream stream = 
      new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
    formatter.Serialize(stream, this);
    stream.Close();
    return true;
}

The Paperless Desktop - A way to clean up?

After all this technical stuff, we can afford a little distraction. Accidentally I designed a haunting process oriented adventure.

Players

  • The Physical Document or Letter.
  • A Desktop Perforator.
  • A Clinch Stapler.
  • One or more Standard Lever Arch Files.
  • A Waste Paper Basket.
  • A Scanner.
  • Your PC with Office 2003 and Outlook.
  • The mighty MartinsPaperlessDesktop Application.

Game instructions:

  1. Open the physical document ("paper").
  2. Use envelop with waste paper basket (no, you don't need it for further inquiries).
  3. Use scanner with document (yes, here we are, back on good old Monkey Island!).
  4. Use stapler and perforator with letter.
  5. Use letter with standard lever arch files.
  6. Use MartinsPaperlessDesktop to perform OCR and E-mail export.
  7. Forget, that you ever got a physical document. Start believing: "Oh, I got an email."

Sounds too basic to be a five star adventure? Well, you are probably right, but it works for me. Mostly.

It's obvious, the ultimate goal of a paperless desktop is not archived by software. The answer seems to stay in the process. Bringing peace into your desktop's chaos needs discipline from the moment you open the post box. Feel free to share your own experiences in the article's discussion board. That's all for the moment; thanks for reading - and of course, thanks for voting too.

References

Versions

  • 3 Apr 2007: Additional information
  • 24 Jun 2005: Added search functions
  • 12 Jun 2005: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Martin Welker
CEO Axonic Informationssysteme GmbH, Germany
Germany Germany

You may also be interested in...

Comments and Discussions

 
QuestionExcellent article Pin
AlisterTheDog26-Aug-14 10:32
memberAlisterTheDog26-Aug-14 10:32 
QuestionMODI.dll and AxModi.dll Pin
Member 17570228-Apr-13 20:13
memberMember 17570228-Apr-13 20:13 
QuestionIO error Pin
Member 53855827-Mar-12 0:47
memberMember 53855827-Mar-12 0:47 
Generalhide some page information on MODI Document [modified] Pin
MSAMIMAN29-Mar-10 20:25
memberMSAMIMAN29-Mar-10 20:25 
QuestionHow To Save Image's Directly To Sql as tif [modified] Pin
Member 434681411-Feb-10 12:09
memberMember 434681411-Feb-10 12:09 
Martin, Thanks for your excellent code
I Hope To Help Me
how to save images directly to sql databases and how to open stored tiff from sql like file and show in seperate page
thanks
HAVE A GOOD TIME
modified on Friday, February 12, 2010 5:44 AM

Generalpressing delete button deletes the image in the Axmidocviewer Pin
saurabhdhiiman19-Jan-10 6:51
membersaurabhdhiiman19-Jan-10 6:51 
Generalnice Pin
Md. Marufuzzaman16-Jul-09 0:30
memberMd. Marufuzzaman16-Jul-09 0:30 
GeneralGood Article Pin
Norm .net28-May-09 20:40
groupNorm .net28-May-09 20:40 
GeneralMODI WITH THMBNAIL LEFT PANEL Pin
dhaval.developer23-Mar-09 1:39
memberdhaval.developer23-Mar-09 1:39 
GeneralRe: MODI WITH THMBNAIL LEFT PANEL Pin
Member 458419920-Aug-09 4:15
memberMember 458419920-Aug-09 4:15 
GeneralMy Twain does not work anymore Pin
Ronsch9-Dec-08 0:49
memberRonsch9-Dec-08 0:49 
GeneralCreate empty MODI document [modified] Pin
Ebbhead8916-Jul-08 6:55
memberEbbhead8916-Jul-08 6:55 
GeneralBroken link at the top of the article Pin
George Papoulakis13-Mar-08 2:09
memberGeorge Papoulakis13-Mar-08 2:09 
GeneralRe: Broken link at the top of the article Pin
Martin Welker4-Nov-08 23:08
memberMartin Welker4-Nov-08 23:08 
QuestionNetwork scanners Pin
Ronsch21-Dec-07 4:29
memberRonsch21-Dec-07 4:29 
GeneralVista Pin
Ronsch21-Dec-07 4:27
memberRonsch21-Dec-07 4:27 
GeneralCouldn't create temp dir; check network connect Pin
pnslcs23-Jul-07 3:09
memberpnslcs23-Jul-07 3:09 
AnswerRe: Couldn't create temp dir; check network connect Pin
hjusman20-Jul-08 18:50
memberhjusman20-Jul-08 18:50 
GeneralRe: Couldn't create temp dir; check network connect Pin
benssar11-Feb-09 2:21
memberbenssar11-Feb-09 2:21 
QuestionDrag and Drop Pin
sfath19-Apr-07 10:34
membersfath19-Apr-07 10:34 
GeneralProblem for long running applications that use MODI, 1500 document max! Pin
T-luv5-Apr-07 14:06
memberT-luv5-Apr-07 14:06 
QuestionHow Split Tiff pages and save as seperate tiff file Pin
bhupathidotnet13-Mar-07 20:54
memberbhupathidotnet13-Mar-07 20:54 
AnswerRe: How Split Tiff pages and save as seperate tiff file Pin
SikeMullivan19-Apr-07 2:47
memberSikeMullivan19-Apr-07 2:47 
QuestionRe: How Split Tiff pages and save as seperate tiff file Pin
hjusman20-Jul-08 18:54
memberhjusman20-Jul-08 18:54 
GeneralException Pin
Doppalapudi13-Mar-07 20:10
memberDoppalapudi13-Mar-07 20:10 
GeneralScanner Button Pin
C.DHAKCHINA MOORTHY18-Feb-07 5:52
memberC.DHAKCHINA MOORTHY18-Feb-07 5:52 
GeneralSplit Screen Pin
hootsman11-Jan-07 5:21
memberhootsman11-Jan-07 5:21 
GeneralRe: Split Screen Pin
Martin Welker11-Mar-07 1:23
memberMartin Welker11-Mar-07 1:23 
QuestionRe: Split Screen Pin
hootsman11-Mar-07 20:59
memberhootsman11-Mar-07 20:59 
GeneralReleasing Images Pin
MeBrainBug17-Dec-06 21:40
memberMeBrainBug17-Dec-06 21:40 
GeneralRe: Releasing Images Pin
FunkySteve30-Jan-07 4:30
memberFunkySteve30-Jan-07 4:30 
QuestionAbout MartinsPaperlessDesktop Pin
i_islamian10-Nov-06 22:44
memberi_islamian10-Nov-06 22:44 
QuestionHow can I display the scanner settings dialog without starting the scan process? Pin
DJM16-Oct-06 0:34
memberDJM16-Oct-06 0:34 
AnswerRe: How can I display the scanner settings dialog without starting the scan process? Pin
Martin Welker23-Jan-07 2:59
memberMartin Welker23-Jan-07 2:59 
GeneralOpening files from a network share Pin
hootsman3-Oct-06 23:45
memberhootsman3-Oct-06 23:45 
QuestionHow to verify that our Scanned image was rotated or not Pin
davelalit5-Sep-06 23:11
memberdavelalit5-Sep-06 23:11 
AnswerRe: How to verify that our Scanned image was rotated or not Pin
Martin Welker6-Sep-06 4:07
memberMartin Welker6-Sep-06 4:07 
QuestionHow to select perticular area of image Pin
Mukesh Naval10-Aug-06 19:09
memberMukesh Naval10-Aug-06 19:09 
QuestionHow to export the result of OCR to a word document? Pin
zeroluo6-Aug-06 21:37
memberzeroluo6-Aug-06 21:37 
AnswerRe: How to export the result of OCR to a word document? Pin
Martin Welker7-Aug-06 21:57
memberMartin Welker7-Aug-06 21:57 
GeneralNeed advise regarding 3rd Party Controls Pin
Xkaliber4-Jun-06 20:01
memberXkaliber4-Jun-06 20:01 
GeneralPassing (WIA image or picturebox) to MODI.document Pin
asimoes7-Apr-06 1:57
memberasimoes7-Apr-06 1:57 
GeneralRe: Passing (WIA image or picturebox) to MODI.document Pin
Martin Welker7-Aug-06 21:54
memberMartin Welker7-Aug-06 21:54 
QuestionDrawing graphics over MODI Pin
great_ghost14-Feb-06 5:45
membergreat_ghost14-Feb-06 5:45 
AnswerRe: Drawing graphics over MODI Pin
Martin Welker14-Feb-06 22:32
memberMartin Welker14-Feb-06 22:32 
AnswerRe: Drawing graphics over MODI Pin
Xkaliber8-Mar-06 3:34
memberXkaliber8-Mar-06 3:34 
GeneralThis Project in VB6 Pin
eumaxx7-Feb-06 1:48
membereumaxx7-Feb-06 1:48 
GeneralRe: This Project in VB6 Pin
Martin Welker14-Feb-06 22:33
memberMartin Welker14-Feb-06 22:33 
GeneralRe: This Project in VB6 Pin
Miguel Lopes7-Aug-06 0:38
memberMiguel Lopes7-Aug-06 0:38 
GeneralRe: This Project in VB6 Pin
MarsWalker27-Dec-06 7:28
memberMarsWalker27-Dec-06 7:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150731.1 | Last Updated 5 Apr 2007
Article Copyright 2005 by Martin Welker
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid