|
I've Done this with a timer.
private void timer1_Tick(object sender, EventArgs e)
{
if (!inited)
{
try
{
tw = new Twain();
tw.Init(this.Handle);
if (tw.FindScanner())
{
btnScan.Enabled = true;
inited = true;
timer1.Enabled = false;
}
else
{
btnScan.Enabled = false;
}
tw.Finish();
tw = null;
}
catch { }
}
}
"tw.FindScanner()" is a function call to the twain class
public bool FindScanner()
{
if (srcds.Version.Language == XXXInitialValueXXX)
{
return false;
}
if (srcds.Version.Country == XXXInitialValueXXX)
{
return false;
}
if (srcds.Version.Info == XXXInitialValueXXX)
{
return false;
}
if (srcds.ProtocolMajor == XXXInitialValueXXX)
{
return false;
}
if (srcds.ProtocolMinor == XXXInitialValueXXX)
{
return false;
}
if (srcds.SupportedGroups == XXXInitialValueXXX)
{
return false;
}
if (srcds.Manufacturer == XXXInitialValueXXX)
{
return false;
}
if (srcds.ProductFamily == XXXInitialValueXXX)
{
return false;
}
if (srcds.ProductName == XXXInitialValueXXX)
{
return false;
}
else { return true; }
}
this function can be customised for finding a particular scanner
|
|
|
|
|
if you have solve the problem ,please send me sptyangzhou@gmail.com,thank you!
|
|
|
|
|
is it possible to set the Dpi 100*100 before strating Scan.
|
|
|
|
|
here it says the scanner to scan with 72 dpi
f32.FromFloat(36);
tc = new TwCapability(TwCap.IYResolution, short.Parse(f32.ToFloat().ToString()));
rc = DScap(appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Set, tc);
if (rc != TwRC.Success)
{
CloseSrc();
return;
}
|
|
|
|
|
I'm echoing 3 previous threads in the hope it might get answered: No matter what resolution the file is scanned it it gets saved at 96 dpi. How can this be tweaked to, say, 300 dpi?
|
|
|
|
|
Here's how I set the resolution of my saved .png file to match the resolution of my scanned image:
Add these:
using System.Runtime.InteropServices;
using System.Reflection;
using System.Drawing;
using System.Drawing.Imaging;
And also add these:
[DllImport("kernel32.dll", ExactSpelling = true)]
internal static extern IntPtr GlobalLock(IntPtr handle);
[DllImport("kernel32.dll", ExactSpelling = true)]
internal static extern IntPtr GlobalFree(IntPtr handle);
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); const UInt32 SWP_NOSIZE = 0x0001; const UInt32 SWP_NOMOVE = 0x0002; const UInt32 SWP_SHOWWINDOW = 0x0040; // Call this way: SetWindowPos(theWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
[DllImport("gdiplus.dll", ExactSpelling = true)]
internal static extern int GdipDisposeImage(IntPtr image);
[DllImport("gdiplus.dll", ExactSpelling = true)]
internal static extern int GdipCreateBitmapFromGdiDib(IntPtr bminfo, IntPtr pixdat, ref IntPtr image);
[StructLayout(LayoutKind.Sequential, Pack = 2)]
internal class BITMAPINFOHEADER
{
public int biSize;
public int biWidth;
public int biHeight;
public short biPlanes;
public short biBitCount;
public int biCompression;
public int biSizeImage;
public int biXPelsPerMeter;
public int biYPelsPerMeter;
public int biClrUsed;
public int biClrImportant;
}
Then add these helper functions:
private static ImageCodecInfo GetEncoderInfo(String pFileExtension)
{
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
for (int j = 0; j < encoders.Length; ++j)
{
if (encoders[j].FilenameExtension.Contains(pFileExtension))
return encoders[j];
}
return null;
}
// Get a pointer to the bitmap's pixel info.
private static IntPtr GetPixelInfo(IntPtr pBmpptr, ref float xDpi, ref float yDpi)
{
BITMAPINFOHEADER bmi = new BITMAPINFOHEADER();
Marshal.PtrToStructure(pBmpptr, bmi);
const float metersPerInch = .0254f;
xDpi = bmi.biXPelsPerMeter * metersPerInch;
yDpi = bmi.biYPelsPerMeter * metersPerInch;
if (bmi.biSizeImage == 0)
bmi.biSizeImage = ((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3) * bmi.biHeight;
int p = bmi.biClrUsed;
if ((p == 0) && (bmi.biBitCount <= 8))
p = 1 << bmi.biBitCount;
p = (p * 4) +
bmi.biSize + // Size of the BITMAPINFOHEADER struct.
(int)pBmpptr; // Pointer to the beginning of the image
return (IntPtr)p;
}
Now here's how to set the resolution of the saved .png file to match the resolution of the scanned image:
IntPtr bmpptr = GlobalLock(hBitmap);
float xDpi = 0.0f;
float yDpi = 0.0f;
// Get a pointer to the bitmap's pixel info
IntPtr pixptr = GetPixelInfo(bmpptr, ref xDpi, ref yDpi); // Get a pointer to the bitmap's pixel info
IntPtr img = IntPtr.Zero;
// Save the dib as a Bitmap object into pointer img
int st = GdipCreateBitmapFromGdiDib(bmpptr, pixptr, ref img);
ImageCodecInfo ici = GetEncoderInfo(".PNG");
MethodInfo mi = typeof(Bitmap).GetMethod("FromGDIplus", BindingFlags.Static | BindingFlags.NonPublic);
Bitmap bitmap = (Bitmap)mi.Invoke(null, new object[] { img });
bitmap.SetResolution(xDpi, yDpi);
ImageFormat imageFormat = new ImageFormat(ici.FormatID);
bitmap.Save(@"c:\MyFolder", imageFormat);
GdipDisposeImage(img);
if (hBitmap != IntPtr.Zero)
{
GlobalFree(hBitmap);
}
modified on Friday, July 22, 2011 3:59 PM
|
|
|
|
|
I find this utility useful, but would also like to be able to load files from saved bmp/jpf/gif etc files so the gdi window looks the same as when it was first scanned via the twain library.
How easy is that to do?
modified on Thursday, January 17, 2008 9:29:20 AM
|
|
|
|
|
Hi,
I have a MFP Xerox M20i with duplex facility. I was made all specification about to duplex scanning without positive results. There is not error when send the message.
Please help me urgently.
Thanks a lot.
Pedro
|
|
|
|
|
excuse me....
Hey there!
Could anyone help you in my problem?
....im making a thsesis on the Filing system but i do not know the codes for connecting an imaging scanner, and making manageable/editable folders where i can also save the scanned images.....
thanks
|
|
|
|
|
For simply scanning images with twain, I have a library on my site with a demo program. It is very minimalistic, but for those of you who just want to start scanning as easy and fast as possible, its a little bit better than this one on CodeProject.
URL: http://pksoft.hu/node/5
|
|
|
|
|
hai.. iam new to dotnet.
iam working with the image scanner..
i want to change the resolution of the image within the code..
how it is posible with this code..
please anyone help me.
its urgent.
thank u very much..
|
|
|
|
|
hai..... iam new to .net.
iam working with the TWAIN image scanner.
this code is very nice.
my problem is changing the resolution with in the code.
anyone please help me.
its very urgent.
thank u very much....
vissu
|
|
|
|
|
I have taken some of the source and written a new Class Library. I then created a small test form, using this new dll. When calling
Result = Twain.NET.Interop.Twain32.DSMparent(ApplicationID, IntPtr.Zero, DataGroup.Control, DataType.Parent, Message.OpenDSM, Hwnd)
My code crashes, giving me a protected memory error. Does this mean it's impossible to run this code from a DLL?
Update: It's not because of the DLL, tested it with the code in a winapp aswell.
Here's the DLLImport:
Imports System.Runtime.InteropServices
Namespace Twain.NET.Interop
Public Class Twain32
Private Const DLL As String = "twain_32.dll"
#Region " DSM * "
<DllImport(DLL, EntryPoint:="#1")> _
Friend Shared Function DSMparent(<[In](), Out()> ByVal Origin As Twain.NET.Identity, ByVal zeroptr As IntPtr, ByVal DataGroup As Twain.NET.DataGroup, ByVal DataType As Twain.NET.DataType, ByVal Message As Twain.NET.Message, ByRef refptr As IntPtr) As Twain.NET.ResultCode
End Function
modified on Saturday, December 08, 2007 11:48:59 PM
|
|
|
|
|
I have moved the code to the form application, but still the same error. Unsure why, can't find the reason.
Since I am kind-off stuck, I tested your demo, and found a bug in the PassMessag code. My scanner is a WIA device, don't know if this is part of the issue, but when I pressed cancel in the Preview/Scan page, the application froze up. Here's something I added to the Switch and removed the small if above it:
case TwainCommand.Not:
{
return false;
}
case TwainCommand.Null:
{
EndingScan();
return false;
}
The new code is in the TwainCommand.Null section, if you cancel, you'll get this command. This kills the listen loop, unfreezing the application.
|
|
|
|
|
yes this problem with win 7 professional with framework2. i need a solution.
with framework1 work perfet
|
|
|
|
|
i have used this code with another scanner and it worked fine.
using it with a HP C4180, the scanner dialog will open and it will do a preview scan.
when i then click the "Accept" button in the scanner dialog, it will say "Preparing To Scan..."
and an empty progress bar. then nothing happens and the scanner driver hangs up.
it seems that it does not process the imessagefilter. when i add:
TwainCommand cmd = tw.PassMessage(ref m);
if (cmd == TwainCommand.Not)
return false;
<b>MessageBox.Show(cmd.ToString());</b>
switch (cmd)
...
no messagebox will pop up.
Anyone know why this happens and how to get around it ?
The scanner driver has the following info:
HP Scanning: 4.0
sct: 1
bdt: 0
fw:
agent: IE 7
script engine: 5.7.5730
agent version: 4.0 (compatible; msie 7.0; windows nt 5.1; .net clr 2.0.50727)
the scanning process works in irfanview, so it must be a problem in the code and
not in the driver.
any help is appreciated, thanks.
|
|
|
|
|
hi
i have the same problem you have if you find the solution please writ it
|
|
|
|
|
Hello, thank you for the code you provided.
I'm trying to make a custom acquisition interface for a scanner device and while doing some tests I modified your Aquire() function:
[...]
TwUserInterface Guif = new TwUserInterface();
Guif.ShowUI = 0;
Guif.ModalUI = 1;
Guif.ParentHand = _hwnd;
ReturnCode = DSuserif(_appid, _srcds, TwDG.Control, TwDAT.UserInterface, TwMSG.EnableDS, Guif);
if (ReturnCode != TwRC.Success)
{
CloseSrc();
return;
}
[...]
but it does not seem to work. VS2005 blocks the execution throwing an AccessViolationException right when executing the DSuserif function. Could anyone help me please?
Thank you. Giulio.
|
|
|
|
|
If someone could be interested in...
I solved this problem by installing a fictitious TWAIN device (TWAIN_32 Sample Source see http://www.twain.org/devfiles/twainkit.exe[^]
), and using the previous code it seems to work correctly.
Hence the source of the problem was the device I used formerly (webcam).
Check your devices if they support own-SourceUi disabling.
|
|
|
|
|
I have faced the same problem. What I used is a webcam.
DSuserif will cause exception AccessViolationException: "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
When I debug the source, or run the release program complied with the source, the exception will be launched always. The IDE I used is VS2008. OS is Vista.
But if I directly execute 'TwainGui.exe' downloaded from CodeProject, it will be successful with no exception launched.
Thanks for help!
|
|
|
|
|
Thanks for the c# twain sample program. It saved me at least months of time. Right now I have problem saving image to tiff file with group4 encoding or compression.
please help me...
|
|
|
|
|
I have the same problem "saving image to tiff file with group4 compression." . Could you find a solution yet,
Thanks
|
|
|
|
|
this code will save multi page Tiff in Group 4 Fax Compression
----------------------------------------------------
private EncoderParameters GetEncoderParameters(int pageIndex, PixelFormat _PixelFormat,
bool isMultiPageImage)
{
try
{
Encoder myEncoder;
EncoderParameter myEncoderParameter;
EncoderParameters myEncoderParameters = null;
//=====================
//For Multi Page Image
//=====================
if ((pageIndex == 0) && (isMultiPageImage == true))
{
// Save the first page (frame).
if (_PixelFormat == PixelFormat.Format1bppIndexed)
{
myEncoderParameters = new EncoderParameters(2);
myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionCCITT4);
myEncoderParameters.Param[1] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
}
else
{
myEncoderParameters = new EncoderParameters(1);
myEncoderParameter = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
myEncoderParameters.Param[0] = myEncoderParameter;
}
}
else if ((pageIndex > 0) && (isMultiPageImage == true))
{
// Save the second page (frame).
if (_PixelFormat == PixelFormat.Format1bppIndexed)
{
myEncoderParameters = new EncoderParameters(2);
myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionCCITT4);
myEncoderParameters.Param[1] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage);
}
else
{
myEncoderParameters = new EncoderParameters(1);
myEncoderParameter = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage);
myEncoderParameters.Param[0] = myEncoderParameter;
}
}
//=====================
//For Single Page Image
//=====================
else if ((pageIndex == 0) && (isMultiPageImage == false))
{
myEncoderParameters = new EncoderParameters(1);
if (_PixelFormat == PixelFormat.Format1bppIndexed)
{
myEncoderParameter = new EncoderParameter(new Encoder(Encoder.Compression.Guid), (long)EncoderValue.CompressionCCITT4);
myEncoderParameters.Param[0] = myEncoderParameter;
}
else
{
myEncoderParameter = new EncoderParameter(new Encoder(Encoder.Compression.Guid), (long)EncoderValue.CompressionLZW);
myEncoderParameters.Param[0] = myEncoderParameter;
}
}
return myEncoderParameters;
}
catch (Exception ex)
{
throw ex;
}
}
------------
private ImageCodecInfo GetEncoderInfo(String mimeType)
{
int j;
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for (j = 0; j < encoders.Length; ++j)
{
if (encoders[j].MimeType == mimeType)
return encoders[j];
}
return null;
}
---------
private void SaveAllPages(Bitmap b, String targetFile)
{
try
{
int pageCount = b.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page);
bool isMultiPage;
if (pageCount == 1)
isMultiPage = false;
else
isMultiPage = true;
Bitmap[] multiPageBMP = new Bitmap[pageCount];
int i;
for (i = 0; i < pageCount; i++)
{
b.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, i);
multiPageBMP[i] = b.Clone();
}
ImageCodecInfo myImageCodecInfo;
myImageCodecInfo = GetEncoderInfo("image/tiff");
b = multiPageBMP[0].Clone(new Rectangle(0, 0, multiPageBMP[0].Width, multiPageBMP[0].Height), multiPageBMP[0].PixelFormat);
for (i = 0; i < multiPageBMP.Length; i++)
{
if (i == 0)
{
// Save the first page (frame).
b.Save(targetFile, myImageCodecInfo, GetEncoderParameters(0, b.PixelFormat, isMultiPage));
}
else
{
// Save the second page (frame).
b.SaveAdd(multiPageBMP[i], GetEncoderParameters(i, b.PixelFormat, isMultiPage));
}
multiPageBMP[i].Dispose();
}
if (isMultiPage == true)
{
EncoderParameters myEncoderParameters = new EncoderParameters(1);
myEncoderParameters.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.Flush);
b.SaveAdd(myEncoderParameters);
}
}
catch (Exception ex)
{
throw ex;
}
}
Salman Khan
|
|
|
|
|
i m making an application to scan multiple forms, 100 pages per minute using twain in black & white.
so far the application made scans only 1 page, i want to scan and save multiple pages to the directory i want. can anyone tell me what steps shall i perform in order to achieve that,
|
|
|
|
|
u need to set de capability XferCount = -1
something like this--»
TwCapability cap = new TwCapability(TwCap.XferCount, -1, TwType.Int16);
rc = DScap(appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Set, cap);
if ((rc != TwRC.Success)) {
CloseSrc();
return;
}
|
|
|
|
|