Возможно ли в TWAIN заставить сканер установить область на всю ширину?

Я пишу приложение, которое требует сканирования в .net (c# версия4.0Visual Studio 2010). Я'м, используяTWAIN API, чтобы сделать сканирование, и у меня есть проблема с функцией макета. Следующий код прекрасно работает наMicrotek i800,CanoScan 9000F иMicrotek Artix Scan F2 но когда я запускаю его противEpson Perfection V700 происходит нечто действительно странное.

Хотя я устанавливаю левый край макета в0 левый край изображения обрезан. Я пытался установить его на отрицательные значения, но это не имело значения. Кажется, что есть какая-то странность, и она заставляет его быть размером с пленку (возможно, потому что я включаю свет). Если я использую инструмент, который поставляется со сканером, он позволяет мне выбрать область, которая включает в себя оба края (и с включенным светом), поэтому это должно быть возможно. Кроме того, верхняя и нижняя координаты работают отлично.

Итак, мой вопрос ...

Кто-нибудь знает, как я могу заставить его сканировать всю ширину? Есть ли какие-то другие настройки в TWAIN, которые я могу установить в первую очередь, чтобы они могли забыть о размерах бумаги? (Я пытался установить для PaperDetectable значение false, но это не имело значения).

Еще одна вещь:Если я не установлю макет, он все равно обрезает изображение по краям (только не сверху и снизу), но если я также не включаю свет (или я не включаю свет, но я устанавливаю размер) он делает то, что я ожидал: специально сканирует всю картинку с самого левого края (но проблема в том, что мне действительно нужен свет и вся ширина сканирования - конечно, это не так.Слишком много, чтобы спросить ...).

Вот код (это код для приложения формы 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:\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 Scan(TwainIdentity appid, 
                                         TwainIdentity scanner)
        {
            var pictures = new List();          

            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");
        }
    }
}

Для полноты вот код, который я использую для преобразования 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 

Ответы на вопрос(1)

Ваш ответ на вопрос