Click here to Skip to main content
Click here to Skip to main content

.NET TWAIN image scanner

By , 12 May 2002
 

Sample Screenshot

Abstract

In Windows imaging applications, the most used API for scanning is TWAIN www.twain.org. Unfortunately, the new .NET Framework has no built-in support for TWAIN. So we have to work with the interop methods of .NET to access this API. This article doesn't explain this interop techniques, and good knowledge of the TWAIN 1.9 specifications is assumed! The sample code included doesn't present a finished library, only some essential steps for a minimal TWAIN adaption to .NET applications.

Details

First step was to port the most important parts of TWAIN.H, these are found in TwainDefs.cs. The real logic for calling TWAIN is coded in the class Twain, in file TwainLib.cs.. As the TWAIN API is exposed by the Windows DLL, twain_32.dll, we have to use the .NET DllImport mechanism for interop with legacy code. This DLL has the central DSM_Entry(), ordinal #1 function exported as the entry point to TWAIN. This call has numerous parameters, and the last one is of variable type! It was found to be best if we declare multiple variants of the call like:

[DllImport("twain_32.dll", EntryPoint="#1")]
private static extern TwRC DSMparent(
    [In, Out] TwIdentity origin,
    IntPtr zeroptr,
    TwDG dg, TwDAT dat, TwMSG msg,
    ref IntPtr refptr );

The Twain class has a simple 5-step interface:

class Twain
{
    Init();
    Select();
    Acquire();
    PassMessage();
    TransferPictures();
}

For some sort of 'callbacks', TWAIN uses special Windows messages, and these must be caught from the application-message-loop. In .NET, the only way found was IMessageFilter.PreFilterMessage(), and this filter has to be activated with a call like Application.AddMessageFilter(). Within the filter method, we have to forward each message to Twain.PassMessage(), and we get a hint (enum TwainCommand) back for how we have to react.

Sample App

The sample is a Windows Forms MDI-style application. It has the two TWAIN-related menu items Select Source... and Acquire... Once an image is scanned in, we can save it to a file in any of the GDI+ supported file formats (BMP, GIF, TIFF, JPEG...)

Limitations

All code was only tested on Windows 2000SP2, with an Epson Perfection USB scanner and an Olympus digital photo camera. The scanned picture is (by TWAIN spec) a Windows DIB, and the sample code has VERY little checking against error return codes and bitmap formats. Unfortunately, no direct method is available in .NET to convert a DIB to the managed Bitmap class... Some known problems may show up with color palettes and menus.

Note, TWAIN has it's root in 16-Bit Windows! For a more modern API supported on Windows ME/XP, have a look at Windows Image Acquisition (WIA).

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

About the Author

NETMaster
Web Developer
Switzerland Switzerland
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
AnswerRe: Out of Memory ExceptionmemberJaydeep Jadav1 Mar '13 - 23:18 
I fixed it by forcing GC to collect garbage after every transfer of picture.   I used GC.Finalize()   Thanks and Regards, Jaydeep Jadav
QuestionLoader Lock Error Problemmemberleenak8 Jun '12 - 2:11 
Please help on this .. when I run the program I am able to select the scanner but when I click Acquire image it gives me exception as below   LoaderLock was detected Message: Attempting managed execution inside OS Loader lock. Do not attempt to run managed code inside a DllMain or...
GeneralRe: Loader Lock Error Problem [modified]membersmile869110 Jul '12 - 11:59 
I have the same problem. Did you find any solutions? Thanks.
QuestionDuplex ScanningmemberIsuru Alahakoon8 Jun '12 - 1:14 
Great article. Thank you very much. But I want to enable duplex scan using this code. Can anyone help me. Thank you.
Questionhide progress bar window.memberMember 46759534 Jun '12 - 21:32 
I tried many ways to hide progress indicator when ShowuI=False; But not working. Please help me.
QuestionError on 64 bits machinememberdavid bong1 Jun '12 - 6:09 
Hi,   When I downloaded the source code and run debug mode on the 64 bits machine, it throws an error when calling the Init() method. it's complaining invalid format ... please advise asda
AnswerRe: Error on 64 bits machinememberboblogan13 Jun '12 - 6:00 
You might check your project output - and make sure it is specify 32 bit code only...
GeneralRe: Error on 64 bits machinememberAbdullah Çetinkaya22 Jan '13 - 23:33 
where we check 32 bit code in vs ?
Questionset Flatbed or FeadermemberAndrew8231 May '12 - 21:22 
hi, i have a question how set Flatbed of Feader.   in twaindef   CAPFEnabled = 0x1002     in twainlib in acquire method TwCapability capF = new TwCapability(TwCap.CAPFEnabled, 1); rc = DScap(appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Get,...
QuestionCan use project as webmemberramysamir29 May '12 - 0:40 
please i want to ask i can user that classes in asp.net webform
QuestionDo you have code for automatically control scannermembergolanw12 May '12 - 22:52 
The code opens a window to select the parameters I want to redefine the resolution the area of scan etc   Can you send the code golan87@walla.co.il   Thanks
QuestionDLLmemberMember 888329025 Apr '12 - 9:57 
Provide the dll used for development, please.
QuestionHow Can I change scaning variables with c# code?memberRadu23717 Apr '12 - 20:46 
It's posible to change scaning variable from code?
AnswerRe: How Can I change scaning variables with c# code?memberMember 100259915 May '13 - 16:36 
TwUserInterface guif = new TwUserInterface(); guif.ShowUI = 0; guif.ModalUI = 1;
QuestionHow to check scanner is connected befor Acquirememberswapnil7434513 Apr '12 - 21:02 
if scanner is not connected then that freeze whole application so is there any method to check whether any scanner is connected before calling of Acquire?   plz help...
Questionconverting?memberdarkalastair19 Mar '12 - 22:15 
Hi, thanks for app really very usefull but how can i show scanned image to picturebox?
AnswerRe: converting?memberMember 667621 Oct '12 - 8:58 
bool IMessageFilter.PreFilterMessage( ref Message m ) { TwainCommand cmd = tw.PassMessage( ref m ); if( cmd == TwainCommand.Not ) return false;   switch( cmd ) { case TwainCommand.CloseRequest: { EndingScan(); ...
QuestionTwainLib Visual Studio 2010 Windows 7 64 bitmembersanvi615 Mar '12 - 3:10 
The binary "TestTwainLib.exe" run Ok, but the source show compilation error "LoaderLock" in the: rc = DSM_Ident(appid, IntPtr.Zero, TwDG.TwDG_Control, TwDAT.TwDAT_Identity, TwMSG.TwMSG_CloseDS, SelectedDataSource)   Whats Happen?
AnswerRe: TwainLib Visual Studio 2010 Windows 7 64 bitmemberUstesGreenridge26 Mar '12 - 3:55 
I was getting that until i went into Debug, Exceptions, Managed Debugging Assistants, and turned off LoaderLock exceptions.
AnswerRe: TwainLib Visual Studio 2010 Windows 7 64 bitmemberDanielMarzan14 May '12 - 8:19 
Change the platform target to x86. That should fix this issue.
GeneralRe: TwainLib Visual Studio 2010 Windows 7 64 bitmembersmile869110 Jul '12 - 12:02 
I changed the target and also unmark the exception for the loader lock. still get the error message. Any ideas? Thanks.
GeneralMy vote of 5membermanoj kumar choubey26 Feb '12 - 18:23 
Nice
Questionproblem ..!!!!!!!!!!memberA7mad_22 Feb '12 - 7:43 
When I press acuqire it opens a window from my scanner when I press cancel on it, the whole application get freezed. How to solve this???
QuestionEpson V30 scan problem with 16 bit grayscale tiffmembersmarino6021 Feb '12 - 7:52 
Hy, First of all thanks for the posted code in c # that is perhaps unique in the network.   my question: I have to create an application that scans a document in 16-bit gray scale and saved in TIFF format, uncompressed 600 dpi. Of course I must not use the Epson interface. With the...
QuestionTransferPictures() method returns pics count 1 alwaysmemberappalanaidu Aug20117 Feb '12 - 22:29 
HI all ,   I tried to fix this issue from last 1 month onwards,TransferPictures() method returns pics count 1 alway ,when scanning multiple pages.previously it was working before changed Acquire() method code to set the user selected scanner.I have written the method setscanner()...

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 13 May 2002
Article Copyright 2001 by NETMaster
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid