c# – 在TWAIN中是否可以强制扫描仪将区域设置为整个宽度?
我正在编写一个需要在.net中扫描的应用程序(c#version 4.0,Visual Studio 2010).我正在使用TWAIN API进行扫描,我的布局功能有问题.以下代码在Microtek i800,CanoScan 9000F和Microtek Artix Scan F2上运行得非常好,但是当我对
Epson Perfection V700运行它时,真的很奇怪.
即使我将布局的左边距设置为0,图像的左边缘也会被切断.我尝试将其设置为负值,但这没有任何区别.似乎有一些奇怪的东西,它迫使它成为一个电影大小(也许是因为我正在开灯).如果我使用扫描仪附带的工具,它允许我选择包含两个边缘的区域(并打开灯),因此必须可以.此外,顶部和底部坐标完美地工作. 所以我的问题是……
另外一件事:如果我没有设置布局,它仍然会切断边缘的图片(只是不是顶部和底部),但如果我也没有设置灯光(或者我没有设置灯光,但我做设置尺寸)它做我所期望的:专门从最左边扫描整个画面(但问题是,我真的需要光线和扫描的整个宽度 – 当然,这不是太多问题. ..). 这是代码(它是1个窗体窗体应用程序的代码,后面有一个按钮): using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Windows.Forms; namespace TwainLayoutWindowsFormsApplication { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender,EventArgs e) { TwainIdentity appid = null; TwainIdentity scanner = null; bool enabled = false; try { appid = InitializeTwain(Handle); scanner = GetSource(appid,"EPSON Perfection V700/V750"); Open(appid,scanner); SetLightOn(appid,scanner); SetLayout(appid,scanner); Enable(appid,scanner,Handle); enabled = true; var bmps = Scan(appid,scanner); Disable(appid,scanner); enabled = false; bmps.First().Save(@"c:userspublicscan.bmp",ImageFormat.Bmp); } catch(Exception ex) { MessageBox.Show(ex.Message); } finally { if (appid != null && scanner != null) { if (enabled) { try { Disable(appid,scanner); } catch(InvalidOperationException) { } } Close(appid,scanner); } } } private static void SetLayout(TwainIdentity appid,TwainIdentity scanner) { TwainImageLayout layout = new TwainImageLayout(); var rc = NativeMethods.DSilayout(appid,TwainDataGroups.Image,TwainDataArgumentType.ImageLayout,TwainMessage.Get,layout); // 1 inch from the top and 0 from the left layout.Frame.Top = new TwainFix32(); layout.Frame.Top.Whole = 1; layout.Frame.Left = new TwainFix32(); layout.Frame.Left.Whole = 0; layout.Frame.Right = new TwainFix32(); layout.Frame.Right.Whole = 6; layout.Frame.Bottom = new TwainFix32(); layout.Frame.Bottom.Whole = 3; layout.FrameNumber = 1; layout.PageNumber = 1; layout.DocumentNumber = 1; rc = NativeMethods.DSilayout(appid,TwainMessage.Set,layout); if (rc != TwainReturnCode.Success) throw new InvalidOperationException("Failed to set layout"); var s = new TwainStatus(); rc = NativeMethods.DSstatus(appid,TwainDataGroups.Control,TwainDataArgumentType.Status,s); if (rc != TwainReturnCode.Success) throw new InvalidOperationException("Failed to get layout"); } private IEnumerable<Bitmap> Scan(TwainIdentity appid,TwainIdentity scanner) { var pictures = new List<Bitmap>(); TwainReturnCode rc; IntPtr hbitmap; var pxfr = new TwainPendingXfers(); do { pxfr.Count = 10; hbitmap = IntPtr.Zero; var iinf = new TwainImageInfo(); rc = NativeMethods.DSiinf(appid,TwainDataArgumentType.ImageInfo,iinf); if (rc != TwainReturnCode.Success) throw new InvalidOperationException("Could not INF"); rc = NativeMethods.DSixfer(appid,TwainDataArgumentType.ImageNativeXfer,ref hbitmap); if (rc != TwainReturnCode.XferDone) throw new InvalidOperationException("Could DSI XFER"); rc = NativeMethods.DSpxfer(appid,TwainDataArgumentType.PendingXfers,TwainMessage.EndXfer,pxfr); if (rc != TwainReturnCode.Success) throw new InvalidOperationException("Could DSP XFER"); var bmp = TwainBitmapConvertor.ToBitmap(hbitmap); pictures.Add(bmp); } while (pxfr.Count != 0); NativeMethods.DSpxfer(appid,TwainMessage.StopFeeder,pxfr); return pictures; } private static void Enable(TwainIdentity appid,TwainIdentity scanner,IntPtr hwnd) { var guif = new TwainUserInterface(); guif.ShowUI = 0; guif.ModalUI = 1; guif.ParentHand = hwnd; var rc = NativeMethods.DSuserif(appid,TwainDataArgumentType.UserInterface,TwainMessage.EnableDS,guif); if (rc != TwainReturnCode.Success) throw new InvalidOperationException("Could not enable"); } private static void Disable(TwainIdentity appid,TwainIdentity scanner) { var guif = new TwainUserInterface(); var rc = NativeMethods.DSuserif(appid,TwainMessage.DisableDS,guif); if (rc != TwainReturnCode.Success) throw new InvalidOperationException("Could not disable"); } private static void SetLightOn(TwainIdentity appid,TwainIdentity scanner) { using (var capability = new TwainCapability(TwainCapabilityType.Lightpath,1)) { var rc = NativeMethods.DScap(appid,TwainDataArgumentType.Capability,capability); if (rc != TwainReturnCode.Success) throw new InvalidOperationException("Failed to set light"); } } private static void Close(TwainIdentity appid,TwainIdentity scanner) { NativeMethods.DSMident(appid,IntPtr.Zero,TwainDataArgumentType.Identity,TwainMessage.CloseDS,scanner); } private static void Open(TwainIdentity appid,TwainIdentity scanner) { var rc = NativeMethods.DSMident(appid,TwainMessage.OpenDS,scanner); if (rc != TwainReturnCode.Success) throw new InvalidOperationException("Failed to open"); } private static TwainIdentity InitializeTwain(IntPtr hwndp) { var appid = new TwainIdentity(); appid.Version.MajorNum = 1; appid.Version.MinorNum = 0; appid.Version.Language = 13; appid.Version.Country = 1; appid.Version.Info = "Test"; appid.Id = IntPtr.Zero; appid.ProtocolMajor = 1; appid.ProtocolMinor = 9; appid.SupportedGroups = (int)(TwainDataGroups.Image | TwainDataGroups.Control); appid.Manufacturer = "Test Manufacturer"; appid.ProductFamily = "Test Family"; appid.ProductName = "Test Product"; var rc = NativeMethods.DSMparent(appid,TwainDataArgumentType.Parent,TwainMessage.OpenDSM,ref hwndp); if (rc != TwainReturnCode.Success) throw new InvalidOperationException("Could Not DSMParent"); return appid; } private static TwainIdentity GetSource(TwainIdentity appid,string name) { var device = new TwainIdentity { Id = IntPtr.Zero }; var rc = NativeMethods.DSMentry(appid,TwainMessage.GetFirst,device); if (rc != TwainReturnCode.EndOfList && device.ProductName.Equals(name,StringComparison.OrdinalIgnoreCase)) { return device; } while (rc != TwainReturnCode.EndOfList) { device = new TwainIdentity { Id = IntPtr.Zero }; rc = NativeMethods.DSMentry(appid,TwainMessage.GetNext,device); if (rc != TwainReturnCode.EndOfList && device.ProductName.Equals(name,StringComparison.OrdinalIgnoreCase)) { return device; } } throw new InvalidOperationException("Could not find device"); } } } 为了完整性,这里是我用来将HBITMAP转换为System.Drawing.Bitmap的代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Diagnostics; using System.Drawing; using System.Runtime.InteropServices; using System.Globalization; namespace TwainLayoutWindowsFormsApplication { internal static class TwainBitmapConvertor { [StructLayout(LayoutKind.Sequential,Pack = 2)] private class BitmapInfoHeader { public int Size; public int Width; public int Height; public short Planes; public short BitCount; public int Compression; public int SizeImage; public int XPelsPerMeter; public int YPelsPerMeter; public int ClrUsed; public int ClrImportant; } internal static Bitmap ToBitmap(IntPtr dibHandle) { var bitmapPointer = NativeMethods.GlobalLock(dibHandle); var bitmapInfo = new BitmapInfoHeader(); Marshal.PtrToStructure(bitmapPointer,bitmapInfo); var rectangle = new Rectangle(); rectangle.X = rectangle.Y = 0; rectangle.Width = bitmapInfo.Width; rectangle.Height = bitmapInfo.Height; if (bitmapInfo.SizeImage == 0) { bitmapInfo.SizeImage = ((((bitmapInfo.Width * bitmapInfo.BitCount) + 31) & ~31) >> 3) * bitmapInfo.Height; } // The following code only works on x86 if (Marshal.SizeOf(typeof(IntPtr)) != 4) throw new NotSupportedException("Only x86 is supported"); int pixelInfoPointer = bitmapInfo.ClrUsed; if ((pixelInfoPointer == 0) && (bitmapInfo.BitCount <= 8)) { pixelInfoPointer = 1 << bitmapInfo.BitCount; } pixelInfoPointer = (pixelInfoPointer * 4) + bitmapInfo.Size + bitmapPointer.ToInt32(); IntPtr pixelInfoIntPointer = new IntPtr(pixelInfoPointer); var bitmap = new Bitmap(rectangle.Width,rectangle.Height); using (Graphics graphics = Graphics.FromImage(bitmap)) { IntPtr hdc = graphics.GetHdc(); try { NativeMethods.SetDIBitsToDevice(hdc,rectangle.Width,rectangle.Height,pixelInfoIntPointer,bitmapPointer,0); } finally { graphics.ReleaseHdc(hdc); } } bitmap.SetResolution(PpmToDpi(bitmapInfo.XPelsPerMeter),PpmToDpi(bitmapInfo.YPelsPerMeter)); NativeMethods.GlobalUnlock(dibHandle); NativeMethods.GlobalFree(dibHandle); return bitmap; } private static float PpmToDpi(double pixelsPerMeter) { double pixelsPerMillimeter = (double)pixelsPerMeter / 1000.0; double dotsPerInch = pixelsPerMillimeter * 25.4; return (float)Math.Round(dotsPerInch,2); } } } 这是p / invokes: using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace TwainLayoutWindowsFormsApplication { internal static class NativeMethods { [DllImport("kernel32.dll",ExactSpelling = true)] internal static extern IntPtr GlobalAlloc(int flags,int size); [DllImport("kernel32.dll",ExactSpelling = true)] internal static extern IntPtr GlobalLock(IntPtr handle); [DllImport("kernel32.dll",ExactSpelling = true)] internal static extern bool GlobalUnlock(IntPtr handle); [DllImport("kernel32.dll",ExactSpelling = true)] internal static extern IntPtr GlobalFree(IntPtr handle); [DllImport("gdi32.dll",ExactSpelling = true)] public static extern int SetDIBitsToDevice(IntPtr hdc,int xdst,int ydst,int width,int height,int xsrc,int ysrc,int start,int lines,IntPtr bitsptr,IntPtr bmiptr,int color); [DllImport("twain_32.dll",EntryPoint = "#1")] internal static extern TwainReturnCode DSMparent([In,Out] TwainIdentity origin,IntPtr zeroptr,TwainDataGroups dg,TwainDataArgumentType dat,TwainMessage msg,ref IntPtr refptr); [DllImport("twain_32.dll",EntryPoint = "#1")] internal static extern TwainReturnCode DSMident([In,[In,Out] TwainIdentity idds); [DllImport("twain_32.dll",EntryPoint = "#1")] internal static extern TwainReturnCode DSMentry([In,EntryPoint = "#1")] internal static extern TwainReturnCode DSMstatus([In,Out] TwainStatus dsmstat); [DllImport("twain_32.dll",EntryPoint = "#1")] internal static extern TwainReturnCode DSuserif([In,Out] TwainIdentity dest,TwainUserInterface guif); [DllImport("twain_32.dll",EntryPoint = "#1")] internal static extern TwainReturnCode DSevent([In,ref TwainEvent evt); [DllImport("twain_32.dll",EntryPoint = "#1")] internal static extern TwainReturnCode DSstatus([In,[In] TwainIdentity dest,EntryPoint = "#1")] internal static extern TwainReturnCode DScap([In,Out] TwainCapability capa); [DllImport("twain_32.dll",EntryPoint = "#1")] internal static extern TwainReturnCode DSiinf([In,Out] TwainImageInfo imginf); [DllImport("twain_32.dll",EntryPoint = "#1")] internal static extern TwainReturnCode DSixfer([In,ref IntPtr hbitmap); [DllImport("twain_32.dll",EntryPoint = "#1")] internal static extern TwainReturnCode DSMemixfer([In,Out] TwainImageMemXfer memxfr); [DllImport("twain_32.dll",EntryPoint = "#1")] internal static extern TwainReturnCode DSpxfer([In,Out] TwainPendingXfers pxfr); [DllImport("twain_32.dll",EntryPoint = "#1")] internal static extern TwainReturnCode DSilayout([In,Out] TwainImageLayout layout); [DllImport("twain_32.dll",EntryPoint = "#1")] internal static extern TwainReturnCode DSMEntry([In,Out] TwainSetupFileXfer fileXf); } } 最后,需要工作的其他东西(结构和诸如此类): using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace TwainLayoutWindowsFormsApplication { [StructLayout(LayoutKind.Sequential,Pack = 2,CharSet = CharSet.Ansi)] internal class TwainIdentity { public IntPtr Id; public TwainVersion Version; public short ProtocolMajor; public short ProtocolMinor; public int SupportedGroups; [MarshalAs(UnmanagedType.ByValTStr,SizeConst = 34)] public string Manufacturer; [MarshalAs(UnmanagedType.ByValTStr,SizeConst = 34)] public string ProductFamily; [MarshalAs(UnmanagedType.ByValTStr,SizeConst = 34)] public string ProductName; } internal enum TwainReturnCode : short { Success = 0x0000,Failure = 0x0001,CheckStatus = 0x0002,Cancel = 0x0003,DSEvent = 0x0004,NotDSEvent = 0x0005,XferDone = 0x0006,EndOfList = 0x0007,InfoNotSupported = 0x0008,DataNotAvailable = 0x0009 } [StructLayout(LayoutKind.Sequential,CharSet = CharSet.Ansi)] internal struct TwainVersion { public short MajorNum; public short MinorNum; public short Language; public short Country; [MarshalAs(UnmanagedType.ByValTStr,SizeConst = 34)] public string Info; } [Flags] internal enum TwainDataGroups : short { Control = 0x0001,Image = 0x0002,Audio = 0x0004 } [StructLayout(LayoutKind.Sequential,Pack = 2)] internal struct TwainEvent { public IntPtr EventPtr; public short Message; } internal enum TwainDataArgumentType : short { Null = 0x0000,Capability = 0x0001,Event = 0x0002,Identity = 0x0003,Parent = 0x0004,PendingXfers = 0x0005,SetupMemXfer = 0x0006,SetupFileXfer = 0x0007,Status = 0x0008,UserInterface = 0x0009,XferGroup = 0x000a,TwunkIdentity = 0x000b,CustomDSData = 0x000c,DeviceEvent = 0x000d,FileSystem = 0x000e,PassThru = 0x000f,ImageInfo = 0x0101,ImageLayout = 0x0102,ImageMemXfer = 0x0103,ImageNativeXfer = 0x0104,ImageFileXfer = 0x0105,CieColor = 0x0106,GrayResponse = 0x0107,RGBResponse = 0x0108,JpegCompression = 0x0109,Palette8 = 0x010a,ExtImageInfo = 0x010b,SetupFileXfer2 = 0x0301 } internal enum TwainMessage : short { Null = 0x0000,Get = 0x0001,GetCurrent = 0x0002,GetDefault = 0x0003,GetFirst = 0x0004,GetNext = 0x0005,Set = 0x0006,Reset = 0x0007,QuerySupport = 0x0008,XFerReady = 0x0101,CloseDSReq = 0x0102,CloseDSOK = 0x0103,DeviceEvent = 0x0104,CheckStatus = 0x0201,OpenDSM = 0x0301,CloseDSM = 0x0302,OpenDS = 0x0401,CloseDS = 0x0402,UserSelect = 0x0403,DisableDS = 0x0501,EnableDS = 0x0502,EnableDSUIOnly = 0x0503,ProcessEvent = 0x0601,EndXfer = 0x0701,StopFeeder = 0x0702,ChangeDirectory = 0x0801,CreateDirectory = 0x0802,Delete = 0x0803,FormatMedia = 0x0804,GetClose = 0x0805,GetFirstFile = 0x0806,GetInfo = 0x0807,GetNextFile = 0x0808,Rename = 0x0809,Copy = 0x080A,AutoCaptureDir = 0x080B,PassThru = 0x0901 } [StructLayout(LayoutKind.Sequential,Pack = 4)] internal struct TwainWindowMessage { public IntPtr hwnd; public int message; public IntPtr wParam; public IntPtr lParam; public int time; public int x; public int y; } internal enum TwainOn : short { Array = 0x0003,Enum = 0x0004,One = 0x0005,Range = 0x0006,DontCare = -1 } internal enum TwainCapabilityType : short { XferCount = 0x0001,ICompression = 0x0100,IPixelType = 0x0101,IUnits = 0x0102,IXferMech = 0x0103,Author = 0x1000,Caption = 0x1001,FeederEnabled = 0x1002,FeederLoaded = 0x1003,Timedate = 0x1004,SupportedCapabilities = 0x1005,Extendedcaps = 0x1006,AutoFeed = 0x1007,ClearPage = 0x1008,FeedPage = 0x1009,RewindPage = 0x100a,Indicators = 0x100b,SupportedCapsExt = 0x100c,PaperDetectable = 0x100d,UIControllable = 0x100e,DeviceOnline = 0x100f,AutoScan = 0x1010,ThumbnailsEnabled = 0x1011,Duplex = 0x1012,DuplexEnabled = 0x1013,Enabledsuionly = 0x1014,CustomdsData = 0x1015,Endorser = 0x1016,JobControl = 0x1017,Alarms = 0x1018,AlarmVolume = 0x1019,AutomaticCapture = 0x101a,TimeBeforeFirstCapture = 0x101b,TimeBetweenCaptures = 0x101c,ClearBuffers = 0x101d,MaxBatchBuffers = 0x101e,DeviceTimeDate = 0x101f,PowerSupply = 0x1020,CameraPreviewUI = 0x1021,DeviceEvent = 0x1022,SerialNumber = 0x1024,Printer = 0x1026,PrinterEnabled = 0x1027,PrinterIndex = 0x1028,PrinterMode = 0x1029,PrinterString = 0x102a,PrinterSuffix = 0x102b,Language = 0x102c,FeederAlignment = 0x102d,FeederOrder = 0x102e,ReAcquireAllowed = 0x1030,BatteryMinutes = 0x1032,BatteryPercentage = 0x1033,CameraSide = 0x1034,Segmented = 0x1035,CameraEnabled = 0x1036,CameraOrder = 0x1037,MicrEnabled = 0x1038,FeederPrep = 0x1039,Feederpocket = 0x103a,Autobright = 0x1100,Brightness = 0x1101,Contrast = 0x1103,CustHalftone = 0x1104,ExposureTime = 0x1105,Filter = 0x1106,Flashused = 0x1107,Gamma = 0x1108,Halftones = 0x1109,Highlight = 0x110a,ImageFileFormat = 0x110c,LampState = 0x110d,LightSource = 0x110e,Orientation = 0x1110,PhysicalWidth = 0x1111,PhysicalHeight = 0x1112,Shadow = 0x1113,Frames = 0x1114,XNativeResolution = 0x1116,YNativeResolution = 0x1117,XResolution = 0x1118,YResolution = 0x1119,MaxFrames = 0x111a,Tiles = 0x111b,Bitorder = 0x111c,Ccittkfactor = 0x111d,Lightpath = 0x111e,Pixelflavor = 0x111f,Planarchunky = 0x1120,Rotation = 0x1121,Supportedsizes = 0x1122,Threshold = 0x1123,Xscaling = 0x1124,Yscaling = 0x1125,Bitordercodes = 0x1126,Pixelflavorcodes = 0x1127,Jpegpixeltype = 0x1128,Timefill = 0x112a,BitDepth = 0x112b,Bitdepthreduction = 0x112c,Undefinedimagesize = 0x112d,Imagedataset = 0x112e,Extimageinfo = 0x112f,Minimumheight = 0x1130,Minimumwidth = 0x1131,Fliprotation = 0x1136,Barcodedetectionenabled = 0x1137,Supportedbarcodetypes = 0x1138,Barcodemaxsearchpriorities = 0x1139,Barcodesearchpriorities = 0x113a,Barcodesearchmode = 0x113b,Barcodemaxretries = 0x113c,Barcodetimeout = 0x113d,Zoomfactor = 0x113e,Patchcodedetectionenabled = 0x113f,Supportedpatchcodetypes = 0x1140,Patchcodemaxsearchpriorities = 0x1141,Patchcodesearchpriorities = 0x1142,Patchcodesearchmode = 0x1143,Patchcodemaxretries = 0x1144,Patchcodetimeout = 0x1145,Flashused2 = 0x1146,Imagefilter = 0x1147,Noisefilter = 0x1148,Overscan = 0x1149,Automaticborderdetection = 0x1150,Automaticdeskew = 0x1151,Automaticrotate = 0x1152,Jpegquality = 0x1153,Feedertype = 0x1154,Iccprofile = 0x1155,Autosize = 0x1156,AutomaticCropUsesFrame = 0x1157,AutomaticLengthDetection = 0x1158,AutomaticColorEnabled = 0x1159,AutomaticColorNonColorPixelType = 0x115a,ColorManagementEnabled = 0x115b,ImageMerge = 0x115c,ImageMergeHeightThreshold = 0x115d,SupoortedExtImageInfo = 0x115e,Audiofileformat = 0x1201,Xfermech = 0x1202 } internal enum TwainType : short { Int8 = 0x0000,Int16 = 0x0001,Int32 = 0x0002,UInt8 = 0x0003,UInt16 = 0x0004,UInt32 = 0x0005,Bool = 0x0006,Fix32 = 0x0007,Frame = 0x0008,Str32 = 0x0009,Str64 = 0x000a,Str128 = 0x000b,Str255 = 0x000c,Str1024 = 0x000d,Str512 = 0x000e } [StructLayout(LayoutKind.Sequential,Pack = 2)] internal class TwainStatus { public short ConditionCode; public short Reserved; } [StructLayout(LayoutKind.Sequential,Pack = 2)] internal class TwainUserInterface { public short ShowUI; public short ModalUI; public IntPtr ParentHand; } [StructLayout(LayoutKind.Sequential,Pack = 2)] internal class TwainImageInfo { public int XResolution; public int YResolution; public int ImageWidth; public int ImageLength; public short SamplesPerPixel; [MarshalAs(UnmanagedType.ByValArray,SizeConst = 8)] public short[] BitsPerSample; public short BitsPerPixel; public short Planar; public short PixelType; public short Compression; } [StructLayout(LayoutKind.Sequential,Pack = 2)] internal class TwMemory { public uint Flags; public uint Length; IntPtr TheMem; } [StructLayout(LayoutKind.Sequential,Pack = 2)] internal class TwainImageMemXfer { public ushort Compression; public uint BytesPerRow; public uint Columns; public uint Rows; public uint XOffset; public uint YOffset; public uint BytesWritten; [MarshalAs(UnmanagedType.Struct)] TwMemory Memory; } [StructLayout(LayoutKind.Sequential,Pack = 2)] internal struct TwainFix32 { public short Whole; public ushort Frac; } [StructLayout(LayoutKind.Sequential,Pack = 2)] internal class TwainFrame { public TwainFix32 Left; public TwainFix32 Top; public TwainFix32 Right; public TwainFix32 Bottom; } [StructLayout(LayoutKind.Sequential,Pack = 2)] internal class TwainImageLayout { public TwainFrame Frame; public int DocumentNumber; public int PageNumber; public int FrameNumber; } [StructLayout(LayoutKind.Sequential,Pack = 2)] internal class TwainPendingXfers { public short Count; public int EOJ; } [StructLayout(LayoutKind.Sequential,Pack = 2)] internal class TwainSetupFileXfer { [MarshalAs(UnmanagedType.ByValTStr,SizeConst = 255)] public string FileName; public ushort Format; public short VRefNum; } [StructLayout(LayoutKind.Sequential,Pack = 2)] internal class TwainCapability : IDisposable { internal TwainCapability(TwainCapabilityType cap) { Cap = (short)cap; ConType = -1; } internal TwainCapability(TwainCapabilityType cap,short sval) { Cap = (short)cap; ConType = (short)TwainOn.One; Handle = NativeMethods.GlobalAlloc(0x42,6); IntPtr pv = NativeMethods.GlobalLock(Handle); Marshal.WriteInt16(pv,(short)TwainType.Int16); Marshal.WriteInt32(pv,2,(int)sval); NativeMethods.GlobalUnlock(Handle); } ~TwainCapability() { Dispose(false); } public short Cap; public short ConType; public IntPtr Handle; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (Handle != IntPtr.Zero) NativeMethods.GlobalFree(Handle); } } } 解决方法
所以,如果有人感兴趣我最终完全放弃了
TWAIN – 我认为根本不可能.
我做的是安装: > Cygwin(基本安装加gcc-core,make和libusb-win32包) 经过一堆配置,制作和安装后,我终于能够从Cygwin提示符发出此命令: scanimage -t 30 -y 30 --mode Color --depth 8 --resolution 1200 --sharpness 2 --format=tiff --source TPU8x10 > out.tiff 并且你会相信它吗..tiff宽阔而锋利,比TWAIN更好. 所以,这是一个我知道的可怕的kludge,但我没有一大堆选项(它必须是一个Windows,胖客户端应用程序在连接扫描仪的机器上运行),所以我只是启动它: c:cygwinbinbash.exe --login -c "scanimage -t 30 -y 30 --mode Color --depth 8 --resolution 1200 --sharpness 2 --format=tiff --source TPU8x10 > ~/out.tiff" 通过.NET应用程序中的Process,当它返回时,我将文件加载到Bitmap并继续进行,好像刚刚发生了什么怪异(意味着应用程序现在有一大堆额外的先决条件和繁琐的配置步骤,但是,嗯,meh,起诉我). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |