Esempio n. 1
0
        private void DoTransfer(ScannedImageSource.Concrete source, WiaDevice device, WiaItem item)
        {
            if (ScanProfile.PaperSource != ScanSource.Glass && !device.SupportsFeeder())
            {
                throw new NoFeederSupportException();
            }
            if (ScanProfile.PaperSource == ScanSource.Duplex && !device.SupportsDuplex())
            {
                throw new NoDuplexSupportException();
            }

            InitProgress(device);
            ConfigureProps(device, item);

            using (var transfer = item.StartTransfer())
            {
                int pageNumber = 1;
                transfer.PageScanned += (sender, args) =>
                {
                    try
                    {
                        using (args.Stream)
                        {
                            if (args.Stream.Length == 0)
                            {
                                return;
                            }
                            using (var output = Image.FromStream(args.Stream))
                            {
                                ProduceImage(source, output, ref pageNumber);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        ScanException = e;
                    }
                };
                transfer.Progress += (sender, args) => smoothProgress.InputProgressChanged(args.Percent / 100.0);
                using (CancelToken.Register(transfer.Cancel))
                {
                    transfer.Download();

                    if (device.Version == WiaVersion.Wia10 && ScanProfile.PaperSource != ScanSource.Glass)
                    {
                        // For WIA 1.0 feeder scans, we need to repeatedly call Download until WIA_ERROR_PAPER_EMPTY is received.
                        try
                        {
                            while (!CancelToken.IsCancellationRequested)
                            {
                                transfer.Download();
                            }
                        }
                        catch (WiaException e) when(e.ErrorCode == WiaErrorCodes.PAPER_EMPTY)
                        {
                        }
                    }
                }
            }
        }
 private void setupScanner()
 {
     device = WiaDevice.GetFirstScannerDevice().AsScannerDevice();
     // Not checking the device's capabilities: for now, we're working on the assumption that we
     // control the exact model of scanner.
     device.DeviceSettings.DocumentHandlingSelect = this.twoSided ?
                                                    DocumentHandlingSelect.Duplex : DocumentHandlingSelect.Feeder;
     device.DeviceSettings.Pages = numPages * (twoSided ? 2 : 1);
 }
Esempio n. 3
0
 private WiaItem GetItem(WiaDevice device)
 {
     if (ScanProfile.UseNativeUI)
     {
         var  hwnd      = Invoker.Current.InvokeGet(() => DialogParent.Handle);
         bool useWorker = Environment.Is64BitProcess && device.Version == WiaVersion.Wia10;
         if (useWorker)
         {
             WiaConfiguration config;
             using (var worker = workerServiceFactory.Create())
             {
                 config = worker.Service.Wia10NativeUI(device.Id(), hwnd);
             }
             var item = device.FindSubItem(config.ItemName);
             device.Properties.DeserializeEditable(device.Properties.Delta(config.DeviceProps));
             item.Properties.DeserializeEditable(item.Properties.Delta(config.ItemProps));
             return(item);
         }
         else
         {
             return(device.PromptToConfigure(hwnd));
         }
     }
     else if (device.Version == WiaVersion.Wia10)
     {
         // In WIA 1.0, the root device only has a single child, "Scan"
         // https://docs.microsoft.com/en-us/windows-hardware/drivers/image/wia-scanner-tree
         return(device.GetSubItems().First());
     }
     else
     {
         // In WIA 2.0, the root device may have multiple children, i.e. "Flatbed" and "Feeder"
         // https://docs.microsoft.com/en-us/windows-hardware/drivers/image/non-duplex-capable-document-feeder
         // The "Feeder" child may also have a pair of children (for front/back sides with duplex)
         // https://docs.microsoft.com/en-us/windows-hardware/drivers/image/simple-duplex-capable-document-feeder
         var items             = device.GetSubItems();
         var preferredItemName = ScanProfile.PaperSource == ScanSource.Glass ? "Flatbed" : "Feeder";
         return(items.FirstOrDefault(x => x.Name() == preferredItemName) ?? items.First());
     }
 }
Esempio n. 4
0
        private void ConfigureProps(WiaDevice device, WiaItem item)
        {
            if (ScanProfile.UseNativeUI)
            {
                return;
            }

            if (ScanProfile.PaperSource != ScanSource.Glass)
            {
                if (device.Version == WiaVersion.Wia10)
                {
                    device.SetProperty(WiaPropertyId.DPS_PAGES, 1);
                }
                else
                {
                    item.SetProperty(WiaPropertyId.IPS_PAGES, 0);
                }
            }

            if (device.Version == WiaVersion.Wia10)
            {
                switch (ScanProfile.PaperSource)
                {
                case ScanSource.Glass:
                    device.SetProperty(WiaPropertyId.DPS_DOCUMENT_HANDLING_SELECT, WiaPropertyValue.FLATBED);
                    break;

                case ScanSource.Feeder:
                    device.SetProperty(WiaPropertyId.DPS_DOCUMENT_HANDLING_SELECT, WiaPropertyValue.FEEDER);
                    break;

                case ScanSource.Duplex:
                    device.SetProperty(WiaPropertyId.DPS_DOCUMENT_HANDLING_SELECT, WiaPropertyValue.FEEDER | WiaPropertyValue.DUPLEX);
                    break;
                }
            }
            else
            {
                switch (ScanProfile.PaperSource)
                {
                case ScanSource.Feeder:
                    item.SetProperty(WiaPropertyId.IPS_DOCUMENT_HANDLING_SELECT, WiaPropertyValue.FRONT_ONLY);
                    break;

                case ScanSource.Duplex:
                    item.SetProperty(WiaPropertyId.IPS_DOCUMENT_HANDLING_SELECT, WiaPropertyValue.DUPLEX | WiaPropertyValue.FRONT_FIRST);
                    break;
                }
            }

            switch (ScanProfile.BitDepth)
            {
            case ScanBitDepth.Grayscale:
                item.SetProperty(WiaPropertyId.IPA_DATATYPE, 2);
                break;

            case ScanBitDepth.C24Bit:
                item.SetProperty(WiaPropertyId.IPA_DATATYPE, 3);
                break;

            case ScanBitDepth.BlackWhite:
                item.SetProperty(WiaPropertyId.IPA_DATATYPE, 0);
                break;
            }

            int xRes = ScanProfile.Resolution.ToIntDpi();
            int yRes = xRes;

            item.SetPropertyClosest(WiaPropertyId.IPS_XRES, ref xRes);
            item.SetPropertyClosest(WiaPropertyId.IPS_YRES, ref yRes);

            PageDimensions pageDimensions = ScanProfile.PageSize.PageDimensions() ?? ScanProfile.CustomPageSize;

            if (pageDimensions == null)
            {
                throw new InvalidOperationException("No page size specified");
            }
            int pageWidth  = pageDimensions.WidthInThousandthsOfAnInch() * xRes / 1000;
            int pageHeight = pageDimensions.HeightInThousandthsOfAnInch() * yRes / 1000;

            int horizontalSize, verticalSize;

            if (device.Version == WiaVersion.Wia10)
            {
                horizontalSize =
                    (int)device.Properties[ScanProfile.PaperSource == ScanSource.Glass
                        ? WiaPropertyId.DPS_HORIZONTAL_BED_SIZE
                        : WiaPropertyId.DPS_HORIZONTAL_SHEET_FEED_SIZE].Value;
                verticalSize =
                    (int)device.Properties[ScanProfile.PaperSource == ScanSource.Glass
                        ? WiaPropertyId.DPS_VERTICAL_BED_SIZE
                        : WiaPropertyId.DPS_VERTICAL_SHEET_FEED_SIZE].Value;
            }
            else
            {
                horizontalSize = (int)item.Properties[WiaPropertyId.IPS_MAX_HORIZONTAL_SIZE].Value;
                verticalSize   = (int)item.Properties[WiaPropertyId.IPS_MAX_VERTICAL_SIZE].Value;
            }

            int pagemaxwidth  = horizontalSize * xRes / 1000;
            int pagemaxheight = verticalSize * yRes / 1000;

            int horizontalPos = 0;

            if (ScanProfile.PageAlign == ScanHorizontalAlign.Center)
            {
                horizontalPos = (pagemaxwidth - pageWidth) / 2;
            }
            else if (ScanProfile.PageAlign == ScanHorizontalAlign.Left)
            {
                horizontalPos = (pagemaxwidth - pageWidth);
            }

            pageWidth  = pageWidth < pagemaxwidth ? pageWidth : pagemaxwidth;
            pageHeight = pageHeight < pagemaxheight ? pageHeight : pagemaxheight;

            if (ScanProfile.WiaOffsetWidth)
            {
                item.SetProperty(WiaPropertyId.IPS_XEXTENT, pageWidth + horizontalPos);
                item.SetProperty(WiaPropertyId.IPS_XPOS, horizontalPos);
            }
            else
            {
                item.SetProperty(WiaPropertyId.IPS_XEXTENT, pageWidth);
                item.SetProperty(WiaPropertyId.IPS_XPOS, horizontalPos);
            }
            item.SetProperty(WiaPropertyId.IPS_YEXTENT, pageHeight);

            if (!ScanProfile.BrightnessContrastAfterScan)
            {
                item.SetPropertyRange(WiaPropertyId.IPS_CONTRAST, ScanProfile.Contrast, -1000, 1000);
                item.SetPropertyRange(WiaPropertyId.IPS_BRIGHTNESS, ScanProfile.Brightness, -1000, 1000);
            }
        }
Esempio n. 5
0
        private void DoWia20NativeTransfer(ScannedImageSource.Concrete source, WiaDeviceManager deviceManager, WiaDevice device)
        {
            // WIA 2.0 doesn't support normal transfers with native UI.
            // Instead we need to have it write the scans to a set of files and load those.

            var hwnd  = Invoker.Current.InvokeGet(() => DialogParent.Handle);
            var paths = deviceManager.PromptForImage(hwnd, device);

            if (paths == null)
            {
                return;
            }

            int pageNumber = 1;

            InitProgress(device);

            try
            {
                foreach (var path in paths)
                {
                    using (var stream = new FileStream(path, FileMode.Open))
                        using (var output = Image.FromStream(stream))
                        {
                            int frameCount = output.GetFrameCount(FrameDimension.Page);
                            for (int i = 0; i < frameCount; i++)
                            {
                                output.SelectActiveFrame(FrameDimension.Page, i);
                                ProduceImage(source, output, ref pageNumber);
                            }
                        }
                }
            }
            finally
            {
                foreach (var path in paths)
                {
                    try
                    {
                        File.Delete(path);
                    }
                    catch (Exception e)
                    {
                        Log.ErrorException("Error deleting WIA 2.0 native transferred file", e);
                    }
                }
            }
        }
Esempio n. 6
0
 private void InitProgress(WiaDevice device)
 {
     ProgressTitle = device.Name();
     InvokeStatusChanged();
 }