|
Hai dude,
I am also working in a project with the same situation like you. I found something during my work. Thats ,
1. You can change the resolution in the Scanner Twain driver UI from 300*300 to 100*100 that will make the scanner faster and it ll create small image. Not like what you are getting now. Otherwise you need to compress the file. Eventhough you have to scan 300 page.. So if you scan with 300*300 resolution your Virtual memory ll be not enough even you use 3 GB for virtual memory. So the application ll automatically close.
2.You can use Marshal.FreeHGlobal(img) after saving the img using Gdip.SaveDIBAs(newpic.Text, newpic.GlobalLock(img), newpic.GetPixelInfo(newpic.GlobalLock(img)))
This ll free the virtual memory after saving the image.
But its better you can change the resolution to 100*100 in the before scanning. And to make more faster, change the compression type to JPEG, which you can find in the option which is also in the Twain driver scanner UI.
I think it ll be very helpful for you. If you have any other doubt... Dont hesitate. And I posted some code for Multi image Doc File and MultiImage tif file in this same topic. You can find that also
Raja Chandrasekaran
Dewsoft Solution
-- modified at 10:45 Monday 20th February, 2006
|
|
|
|
|
Hey, I found that if we do not select a source theres a major crash :P
Can someone tell me how to avoid the crash
|
|
|
|
|
To all the interested, to avoid the infinite loop to crash you app do the following...
On the Event to Acquire the image, change the order on tw.Acquire() with the if to open the message interceptor...
Create a public static bool and tell it that it's true,then on Twain and on the function Init right before the end of the method put on the var value true.
Finally come back to the mainform and then only start the message intercceptor if the var is false
Here's some snippet code
<br />
private void menuItemScan_Click(object sender, System.EventArgs e)<br />
{ <br />
tw.Acquire();<br />
if (TwainLib.Twain.failed == false)<br />
{<br />
if( ! msgfilter )<br />
{<br />
this.Enabled = false;<br />
msgfilter = true;<br />
Application.AddMessageFilter( this );<br />
}<br />
}<br />
}<br />
<br />
public static bool failed = false;<br />
public void Init( IntPtr hwndp )<br />
{<br />
Finish();<br />
TwRC rc = DSMparent( appid, IntPtr.Zero, TwDG.Control, TwDAT.Parent, TwMSG.OpenDSM, ref hwndp );<br />
if( rc == TwRC.Success )<br />
{<br />
rc = DSMident( appid, IntPtr.Zero, TwDG.Control, TwDAT.Identity, TwMSG.GetDefault, srcds );<br />
if( rc == TwRC.Success )<br />
hwnd = hwndp;<br />
else<br />
rc = DSMparent( appid, IntPtr.Zero, TwDG.Control, TwDAT.Parent, TwMSG.CloseDSM, ref hwndp );<br />
}<br />
else <br />
failed = true;<br />
}<br />
|
|
|
|
|
Still it doesn't work, if i cancel on the message asking for a scanner my app crashes instantly.
basha
|
|
|
|
|
Hi,
I tried above changes and some other but it is not working and my application goes to infinite loop.
Can u suggest me the changes to be made or else the new mail me the updated version.......its very very urgent sir.....so plz respond soon.
Thx in advance
Sujan
.Net Programmer, Software Engineer
|
|
|
|
|
Hello, I would like to know if using this code can be adapted to sacn directly without opening the scanner GUI, thanks in advance.
|
|
|
|
|
That's a good question...
|
|
|
|
|
Echooff3 has written:
Try this:
TwUserInterface guif = new TwUserInterface();
guif.ShowUI = 0; //***False
guif.ModalUI = 0; //***False
guif.ParentHand = IntPtr.Zero ; //***Nulled
rc = DSuserif( appid, srcds, TwDG.Control, TwDAT.UserInterface, TwMSG.EnableDS, guif );
if( rc != TwRC.Success )
{
CloseSrc();
return;
}
And it works.
|
|
|
|
|
It doesn't work
All I get is a black rectangle. Can you explain how to use it?
|
|
|
|
|
what does this code?
guif.ParentHand
Jwalant Soneji (BE IT)
Mobile: +91 9969059127
http://jnsoneji.spaces.live.com
http://jnsoneji.blogspot.com
|
|
|
|
|
When going throught the scan operation in my app Ive created with your scan code. If the user cancels the scan - there is no message passed back to my app and it hangs. How Can I fix this?
|
|
|
|
|
Hi , I'm get the same problem . I have the code implemented withing a user control to be used on forms the user control has a picture box on it where it displays the scanned image but if the user cancels or doesn't have the scanner connected the whole app just freezes into infinit loop . doesn't even break;
Hamid Basha
|
|
|
|
|
:-Dok i found this to work with my cannon scanner :
1- add Failure to TwainCommand enum
public enum TwainCommand<br />
{<br />
Not = -1,<br />
Null = 0,<br />
TransferReady = 1,<br />
CloseRequest = 2,<br />
CloseOk = 3,<br />
DeviceEvent = 4,<br />
Failure = 5 }
2- add Failure handling to PassMessage
public TwainCommand PassMessage( ref Message m )<br />
{<br />
if( srcds.Id == IntPtr.Zero )<br />
return TwainCommand.Not;<br />
<br />
int pos = GetMessagePos();<br />
<br />
winmsg.hwnd = m.HWnd;<br />
winmsg.message = m.Msg;<br />
winmsg.wParam = m.WParam;<br />
winmsg.lParam = m.LParam;<br />
winmsg.time = GetMessageTime();<br />
winmsg.x = (short) pos;<br />
winmsg.y = (short) (pos >> 16);<br />
<br />
Marshal.StructureToPtr( winmsg, evtmsg.EventPtr, false );<br />
evtmsg.Message = 0;<br />
TwRC rc = DSevent( appid, srcds, TwDG.Control, TwDAT.Event, TwMSG.ProcessEvent, ref evtmsg );<br />
if( rc == TwRC.NotDSEvent )<br />
return TwainCommand.Not;<br />
if (rc == TwRC.Failure)<br />
return TwainCommand.Failure ; if( evtmsg.Message == (short) TwMSG.XFerReady )<br />
return TwainCommand.TransferReady;<br />
if( evtmsg.Message == (short) TwMSG.CloseDSReq )<br />
return TwainCommand.CloseRequest;<br />
if( evtmsg.Message == (short) TwMSG.CloseDSOK )<br />
return TwainCommand.CloseOk;<br />
if (( evtmsg.Message == (short) TwMSG.DeviceEvent ) || ( evtmsg.Message == (short) TwMSG.DeviceEvent )) <br />
return TwainCommand.DeviceEvent;<br />
<br />
<br />
return TwainCommand.Null;<br />
}
3- Add Failure message handling in the PreFilterMessage
bool IMessageFilter.PreFilterMessage( ref Message m )<br />
{<br />
string TemporaryFile;<br />
TwainCommand cmd = tw.PassMessage( ref m );<br />
if( cmd == TwainCommand.Not )<br />
{<br />
<br />
return false;<br />
}<br />
<big>if( cmd == TwainCommand.Failure )<br />
{<br />
EndingScan();<br />
tw.CloseSrc();<br />
return false;<br />
}</big>.<br />
.<br />
.<br />
|
|
|
|
|
Hi, great job!
Currently, I'm able to get a list of available Twain devices (either programmatically or through a twain UI)
Is there a way to know for each installed Twain device if it is a scanner or a webcam (or something else)? Is there a capability, a property, anything that could help me distinguish between scanners an cams.
Same kind of problems: is there a way to prevent Twain to consider WIA devices be correct Twain devices. Each device that is connected to my PC appears twice, the first one matches the twain driver, and the second matches the WIA driver...
thanks
Olivier DALET
|
|
|
|
|
Hi,
im trying to acquire the image in my form with the user interface of the scanner being disabled. Could anyone suggest how to acquire the image with the same feel (in my form) as it is done by the scanner when the user interface is True. i.e. the scanned image being shown as it is being scanned and not loading the image at once ...as the picture is being scanned it should display the same in the form .
Kindly reply its urgent
Grateful till death
sabs
|
|
|
|
|
it is just to try to set the size of the scan. Right now I am getting a scan of 1 in by 1 in or so. I need to scan the whole document with out the interface.
So i need to send the ICAP_Imagelayout
I get a checkstatus from the DSMImageLayout which when i check the status i get a success.
But yet I still do not get a whole scan of the document.
Anybody else had this problem?
Dim flay As New TwImageLayout
Dim ptr1 As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(flay))
Marshal.StructureToPtr(flay, ptr1, False)
Dim ptr2 As IntPtr = ptr1
rc = Me.DSMImageLayout(appid, srcds, TwDG.Image, TwDAT.ImageLayout, TwMSG.Get, ptr1)
Marshal.PtrToStructure(ptr2, flay)
flay.frame.top = 0.0
flay.frame.left = 0.0
flay.frame.right = 6.0
flay.frame.bottom = 10.0
flay.FrameNumber = 1
flay.PageNumber = 1
flay.DocumentNumber = 1
rc = Me.DSMImageLayout(appid, srcds, TwDG.Image, TwDAT.ImageLayout, TwMSG.Set, ptr1)
Dim s As New TwStatus
rc = Me.DSstatus(appid, srcds, TwDG.Control, TwDAT.Status, TwMSG.Get, s)
Thank you
ccalzaretta@cdirad.com
DSMImageLayout
|
|
|
|
|
|
Can't work by this code.
error, it said "TwainLib.TwCap don't include 'IXResolution' definiation"
how solve?
|
|
|
|
|
Where could I find the definition for TwImageLayout, because there isn't one in the sample code? Secondly, where could I find the right definition for DLL importing DSMImageLayout(...)? It's not important if the code is in VB or C#.
Mike
|
|
|
|
|
Hello,
Can anyone show me the way, how i can access Client side Scanner From asp.net page.
I will be glad to receive some example code or advice!
You can also send solutions on my email: email2jasthi@yahoo.com
Thanks in advance!
|
|
|
|
|
Hi,
can anyone tell me, how I can get a list of all resolutions, the scanner supports?
Or at least the valid range or something like that, so that I can display possible values dynamically in a combobox...
It's very urgent!!!
Thanks!
|
|
|
|
|
I can't praise this article enough. Great job NetMaster.
One thing I can't get my head round is how to retrieve the correct values from the ItemList property of the TW_ARRAY and TW_ENUMERATION classes.
What I'm looking to do is query the CAP_SUPPORTEDCAPS capability (populating a TW_ARRAY class) allowing me to know in advance whether I need bother check for capabilities such as CAP_DEVICEONLINE.
Here's what I've done.
1. Created a TwArray class, implementing GetUInt16Array() which I've taken from elsewhere in this forum
[StructLayout(LayoutKind.Sequential, Pack=2)]<br />
internal unsafe class TwArray<br />
{ <br />
public ushort ItemType = 0;<br />
public uint NumItems = 0;<br />
public byte ItemList; <br />
<br />
public unsafe ushort[] GetUInt16Array()<br />
{<br />
ushort[] result = new ushort[NumItems];<br />
<br />
fixed (byte* pSrc = &ItemList)<br />
{ <br />
byte* ps = pSrc;<br />
<br />
for (uint n =0 ; n < NumItems ; n++)<br />
{<br />
result[n] = (ushort)Marshal.ReadInt16((IntPtr)ps);<br />
ps += sizeof(ushort);<br />
}<br />
}<br />
return result;<br />
}<br />
}
2. Modified the TwCapability constructor and added a GetTwArray class.
public TwCapability( TwCap cap, TwOn on_type, TwType type, int val )<br />
{<br />
Cap = (short) cap;<br />
ConType = (short) on_type;<br />
if(on_type != TwOn.DontCare)<br />
{<br />
Handle = Twain.GlobalAlloc( 0x42, 6 );<br />
IntPtr pv = Twain.GlobalLock( Handle );<br />
Marshal.WriteInt16( pv, 0, (short) type);<br />
Marshal.WriteInt32( pv, 2, (int) val );<br />
Twain.GlobalUnlock( Handle );<br />
}<br />
}<br />
<br />
public TwArray GetTwArray()<br />
{ <br />
TwArray arr = (TwArray)Marshal.PtrToStructure(Twain.GlobalLock(Handle), typeof(TwArray));<br />
ushort[] result = arr.GetUInt16Array();<br />
Twain.GlobalFree(Handle);<br />
return arr;<br />
}
3. Implemented the code as follows in the Acquire() method.
TwCapability capAll = new TwCapability(TwCap.SupportedCaps, TwOn.Array, TwType.Int16, -1);<br />
rc = DScap( applicationIdentity, sourceIdentity, TwDG.Control, TwDAT.Capability, TwMSG.Get, capAll);<br />
TwArray arr = capAll.GetTwArray();
Now, when I put a breakpoint in the GetTwArray class and try to view the result array, I get the following. I know the array is the correct length as I've validated it against Twains twack utility, however the values are not as I would expect. There may be a tell tale sign in the fact that the values repeat themselves every 8 occurances, but I don't know what to make of that. Has anyone been able to implement this successfully, or can anyone suggest where I'm going wrong?
{Length=29}
[0]: 1
[1]: 0
[2]: 0
[3]: 20092
[4]: 154
[5]: 29
[6]: 0
[7]: 1
[8]: 0
[9]: 0
[10]: 20092
[11]: 154
[12]: 29
[13]: 0
[14]: 1
[15]: 0
[16]: 0
[17]: 20092
[18]: 154
[19]: 29
[20]: 0
[21]: 1
[22]: 0
[23]: 0
[24]: 20092
[25]: 154
[26]: 29
[27]: 0
[28]: 1
many thanks, in advance
|
|
|
|
|
I'm working on this as well.
My results are:
[0] 1 ushort
[1] 0 ushort
[2] 0 ushort
[3] 51148 ushort
[4] 818 ushort
[5] 23 ushort
[6] 0 ushort
[7] 1 ushort
[8] 0 ushort
[9] 0 ushort
[10] 51148 ushort
[11] 818 ushort
[12] 23 ushort
[13] 0 ushort
[14] 1 ushort
[15] 0 ushort
[16] 0 ushort
[17] 51148 ushort
[18] 818 ushort
[19] 23 ushort
[20] 0 ushort
[21] 1 ushort
[22] 0 ushort
I can't see anything wrong offhand about the approach, but I'll mess around with it some more.
|
|
|
|
|
Okay, I just got it working by doing all the pointer math by hand. Ugly, but hey.
public ushort[] GetTwArray()<br />
{<br />
IntPtr pv = Twain.GlobalLock( Handle );<br />
ushort[] result=null;<br />
unsafe<br />
{<br />
ushort* sp=(ushort*)pv.ToPointer();<br />
uint* ip;<br />
ushort ItemType;<br />
uint NumItems;<br />
ItemType=*sp;<br />
sp++;<br />
ip=(uint*)sp;<br />
NumItems=*ip;<br />
ip++;<br />
sp=(ushort*)ip;<br />
result=new ushort[NumItems];<br />
for (int i=0;i<result.Length;i++)<br />
{<br />
result[i]=*sp;<br />
sp++;<br />
}<br />
}<br />
Twain.GlobalUnlock(Handle);<br />
return result;<br />
}
|
|
|
|
|
Very nice, but i think after all you must free unmanaged memory
|
|
|
|
|