Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否可以用TWAIN强制扫描仪将区域设置为整个宽度?_C#_.net_Twain - Fatal编程技术网

C# 是否可以用TWAIN强制扫描仪将区域设置为整个宽度?

C# 是否可以用TWAIN强制扫描仪将区域设置为整个宽度?,c#,.net,twain,C#,.net,Twain,我正在编写一个需要在.NETC版本4.0 Visual Studio 2010中进行扫描的应用程序。我正在使用TWAINAPI进行扫描,但布局功能有问题。下面的代码在Microtek i800、CanoScan 9000F和Microtek Artix Scan F2上运行得非常好,但是当我针对一个非常奇怪的问题运行它时,会发生一些非常奇怪的事情 即使我将布局的左边缘设置为0,图像的左边缘也会被切断。我试着将其设置为负值,但没有任何区别。这似乎有一些奇怪的地方,它迫使它成为胶片大小,也许是因为我

我正在编写一个需要在.NETC版本4.0 Visual Studio 2010中进行扫描的应用程序。我正在使用TWAINAPI进行扫描,但布局功能有问题。下面的代码在Microtek i800、CanoScan 9000F和Microtek Artix Scan F2上运行得非常好,但是当我针对一个非常奇怪的问题运行它时,会发生一些非常奇怪的事情

即使我将布局的左边缘设置为0,图像的左边缘也会被切断。我试着将其设置为负值,但没有任何区别。这似乎有一些奇怪的地方,它迫使它成为胶片大小,也许是因为我打开了灯。如果我使用扫描仪附带的工具,它允许我选择一个包含两条边的区域,并打开灯光,因此必须可以。此外,顶部和底部坐标工作得非常好

所以我的问题是

有人知道我能让它扫描整个宽度的方法吗?是否有其他设置,我可以先设置,让它忘记纸张大小?我也试着将参数设置为false,但没什么不同

还有一件事:如果我没有设置布局,它仍然会在边缘上切断图片,而不是顶部和底部,但是如果我也没有打开灯,或者我没有打开灯,但我确实设置了大小,它会实现我预期的效果:特别是从最左侧边缘扫描整个图片,但问题是,我真的需要光线和扫描的整个宽度——这当然不是太多要求

下面是代码,这是一个单按钮的1窗体windows窗体应用程序的代码:

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:\users\public\scan.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,
                                             scanner,
                                             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,
                                         scanner,
                                         TwainDataGroups.Image,
                                         TwainDataArgumentType.ImageLayout,
                                         TwainMessage.Set,
                                         layout);
            if (rc != TwainReturnCode.Success)
                throw new InvalidOperationException("Failed to set layout");

            var s = new TwainStatus();

            rc = NativeMethods.DSstatus(appid,
                                        scanner,
                                        TwainDataGroups.Control,
                                        TwainDataArgumentType.Status,
                                        TwainMessage.Get, 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, 
                                          scanner, 
                                          TwainDataGroups.Image, 
                                          TwainDataArgumentType.ImageInfo, 
                                          TwainMessage.Get, 
                                          iinf);
                if (rc != TwainReturnCode.Success)
                    throw new InvalidOperationException("Could not INF");

                rc = NativeMethods.DSixfer(appid, 
                                           scanner, 
                                           TwainDataGroups.Image, 
                                           TwainDataArgumentType.ImageNativeXfer, 
                                           TwainMessage.Get, 
                                           ref hbitmap);
                if (rc != TwainReturnCode.XferDone)
                    throw new InvalidOperationException("Could DSI XFER");

                rc = NativeMethods.DSpxfer(appid, 
                                           scanner, 
                                           TwainDataGroups.Control, 
                                           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, 
                                  scanner, 
                                  TwainDataGroups.Control, 
                                  TwainDataArgumentType.PendingXfers, 
                                  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, 
                                            scanner, 
                                            TwainDataGroups.Control, 
                                            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,
                                            scanner, 
                                            TwainDataGroups.Control, 
                                            TwainDataArgumentType.UserInterface, 
                                            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,
                                             scanner,
                                             TwainDataGroups.Control,
                                             TwainDataArgumentType.Capability,
                                             TwainMessage.Set,
                                             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,
                                   TwainDataGroups.Control,
                                   TwainDataArgumentType.Identity,
                                   TwainMessage.CloseDS,
                                   scanner);
        }

        private static void Open(TwainIdentity appid, TwainIdentity scanner)
        {
            var rc = NativeMethods.DSMident(appid, 
                                            IntPtr.Zero, 
                                            TwainDataGroups.Control, 
                                            TwainDataArgumentType.Identity, 
                                            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,
                                             IntPtr.Zero,
                                             TwainDataGroups.Control,
                                             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, 
                                            IntPtr.Zero, 
                                            TwainDataGroups.Control, 
                                            TwainDataArgumentType.Identity, 
                                            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, 
                                            IntPtr.Zero, 
                                            TwainDataGroups.Control, 
                                            TwainDataArgumentType.Identity, 
                                            TwainMessage.GetNext, 
                                            device);

                if (rc != TwainReturnCode.EndOfList && 
                   device.ProductName.Equals(name, 
                                          StringComparison.OrdinalIgnoreCase))
                {
                    return device;
                }
            }

            throw new InvalidOperationException("Could not find device");
        }
    }
}
最后,剩下的东西结构和其他需要工作的东西:

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, Pack = 2, 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, 0, (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);
        }
    }
}

所以,如果有人感兴趣,我最终完全放弃了——我认为这根本不可能

我所做的是安装:

基本安装外加gcc核心、make和libusb-win32软件包 . 经过一整堆的配置、制作和安装,我终于能够在提示符下发出以下命令:

你会相信吗?蒂芙又宽又尖,比我用它能做到的要好得多

所以,我知道这是一个可怕的乱七八糟的问题,但我没有一大堆的选项。它必须是一个windows厚客户端应用程序,在连接了扫描仪的机器上运行,所以我只启动这个:

c:\cygwin\bin\bash.exe --login -c "scanimage -t 30 -y 30 --mode Color --depth 8 --resolution 1200 --sharpness 2 --format=tiff --source TPU8x10 > ~/out.tiff"

通过.NET应用程序中的a,当它返回时,我将文件加载到a中并继续进行,就好像没有发生任何异常情况一样,这意味着应用程序现在有一大堆额外的先决条件和复杂的配置步骤,但是,嗯,请告我。

对于这么多代码,我建议启动一个悬赏。。
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, Pack = 2, 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, 0, (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);
        }
    }
}
scanimage -t 30 -y 30 --mode Color --depth 8 --resolution 1200 --sharpness 2 --format=tiff --source TPU8x10 > out.tiff
c:\cygwin\bin\bash.exe --login -c "scanimage -t 30 -y 30 --mode Color --depth 8 --resolution 1200 --sharpness 2 --format=tiff --source TPU8x10 > ~/out.tiff"