Пример #1
0
        public Stream Transfer(int pageNumber, WiaBackgroundEventLoop eventLoop, string format)
        {
            if (pageNumber == 1)
            {
                // The only downside of the common dialog is that it steals focus.
                // If this is the first page, then the user has just pressed the scan button, so that's not
                // an issue and we can use it and get the benefits of progress display and immediate cancellation.
                ImageFile imageFile = eventLoop.GetSync(wia =>
                                                        (ImageFile) new CommonDialogClass().ShowTransfer(wia.Item, format));
                if (imageFile == null)
                {
                    return(null);
                }
                return(new MemoryStream((byte[])imageFile.FileData.get_BinaryData()));
            }
            // For subsequent pages, we don't want to take focus in case the user has switched applications,
            // so we use the custom form.
            var form = formFactory.Create <FScanProgress>();

            form.PageNumber = pageNumber;
            form.EventLoop  = eventLoop;
            form.Format     = format;
            form.ShowDialog();
            if (form.Exception != null)
            {
                throw form.Exception;
            }
            if (form.DialogResult == DialogResult.Cancel)
            {
                return(null);
            }
            return(form.ImageStream);
        }
Пример #2
0
 protected override IEnumerable <ScannedImage> ScanInternal()
 {
     using (var eventLoop = new WiaBackgroundEventLoop(ScanProfile, ScanDevice, threadFactory))
     {
         bool supportsFeeder = eventLoop.GetSync(wia => WiaApi.DeviceSupportsFeeder(wia.Device));
         if (ScanProfile.PaperSource != ScanSource.Glass && !supportsFeeder)
         {
             throw new NoFeederSupportException();
         }
         bool supportsDuplex = eventLoop.GetSync(wia => WiaApi.DeviceSupportsDuplex(wia.Device));
         if (ScanProfile.PaperSource == ScanSource.Duplex && !supportsDuplex)
         {
             throw new NoDuplexSupportException();
         }
         int  pageNumber = 1;
         int  retryCount = 0;
         bool retry      = false;
         bool cancel     = false;
         do
         {
             ScannedImage image;
             try
             {
                 if (pageNumber > 1 && ScanProfile.WiaDelayBetweenScans)
                 {
                     int delay = (int)(ScanProfile.WiaDelayBetweenScansSeconds.Clamp(0, 30) * 1000);
                     Thread.Sleep(delay);
                 }
                 image = TransferImage(eventLoop, pageNumber, out cancel);
                 pageNumber++;
                 retryCount = 0;
                 retry      = false;
             }
             catch (ScanDriverException e)
             {
                 if (ScanProfile.WiaRetryOnFailure && e.InnerException is COMException &&
                     (uint)((COMException)e.InnerException).ErrorCode == 0x80004005 && retryCount < MAX_RETRIES)
                 {
                     Thread.Sleep(1000);
                     retryCount += 1;
                     retry       = true;
                     continue;
                 }
                 throw;
             }
             catch (Exception e)
             {
                 throw new ScanDriverUnknownException(e);
             }
             if (image != null)
             {
                 yield return(image);
             }
         } while (retry || (!cancel && ScanProfile.PaperSource != ScanSource.Glass));
     }
 }
Пример #3
0
        public Stream Transfer(int pageNumber, WiaBackgroundEventLoop eventLoop, string format)
        {
            // The console shouldn't spawn new forms, so use the silent transfer method.
            ImageFile imageFile = eventLoop.GetSync(wia => (ImageFile)wia.Item.Transfer(format));

            if (imageFile == null)
            {
                return(null);
            }
            return(new MemoryStream((byte[])imageFile.FileData.get_BinaryData()));
        }
Пример #4
0
        protected override async Task ScanInternal(ScannedImageSource.Concrete source)
        {
            using (var eventLoop = new WiaBackgroundEventLoop(ScanProfile, ScanDevice))
            {
                bool supportsFeeder = eventLoop.GetSync(wia => WiaApi.DeviceSupportsFeeder(wia.Device));
                if (ScanProfile.PaperSource != ScanSource.Glass && !supportsFeeder)
                {
                    throw new NoFeederSupportException();
                }
                bool supportsDuplex = eventLoop.GetSync(wia => WiaApi.DeviceSupportsDuplex(wia.Device));
                if (ScanProfile.PaperSource == ScanSource.Duplex && !supportsDuplex)
                {
                    throw new NoDuplexSupportException();
                }
                int  pageNumber = 1;
                int  retryCount = 0;
                bool retry      = false;
                bool done       = false;
                do
                {
                    ScannedImage image;
                    try
                    {
                        if (pageNumber > 1 && ScanProfile.WiaDelayBetweenScans)
                        {
                            int delay = (int)(ScanProfile.WiaDelayBetweenScansSeconds.Clamp(0, 30) * 1000);
                            Thread.Sleep(delay);
                        }
                        (image, done) = await TransferImage(eventLoop, pageNumber);

                        pageNumber++;
                        retryCount = 0;
                        retry      = false;
                    }
                    catch (ScanDriverException e)
                    {
                        if (ScanProfile.WiaRetryOnFailure && e.InnerException is COMException comError &&
                            (uint)comError.ErrorCode == 0x80004005 && retryCount < MAX_RETRIES)
                        {
                            Thread.Sleep(1000);
                            retryCount += 1;
                            retry       = true;
                            continue;
                        }
                        throw;
                    }
                    if (image != null)
                    {
                        source.Put(image);
                    }
                } while (!CancelToken.IsCancellationRequested && (retry || !done && ScanProfile.PaperSource != ScanSource.Glass));
            }
        }
Пример #5
0
 protected override IEnumerable <ScannedImage> ScanInternal()
 {
     using (var eventLoop = new WiaBackgroundEventLoop(ScanProfile, ScanDevice, threadFactory))
     {
         bool supportsFeeder = eventLoop.GetSync(wia => WiaApi.DeviceSupportsFeeder(wia.Device));
         if (ScanProfile.PaperSource != ScanSource.Glass && !supportsFeeder)
         {
             throw new NoFeederSupportException();
         }
         bool supportsDuplex = eventLoop.GetSync(wia => WiaApi.DeviceSupportsDuplex(wia.Device));
         if (ScanProfile.PaperSource == ScanSource.Duplex && !supportsDuplex)
         {
             throw new NoDuplexSupportException();
         }
         int  pageNumber = 1;
         int  retryCount = 0;
         bool retry      = false;
         bool cancel     = false;
         do
         {
             ScannedImage image;
             try
             {
                 image = TransferImage(eventLoop, pageNumber, out cancel);
                 pageNumber++;
                 Debug.WriteLine("Succeeded with retry count {0}", retryCount);
                 retryCount = 0;
                 retry      = false;
             }
             catch (ScanDriverException e)
             {
                 if (e.InnerException is COMException && (uint)((COMException)e.InnerException).ErrorCode == 0x80004005 && retryCount < 10)
                 {
                     Thread.Sleep(1000);
                     retryCount += 1;
                     Debug.WriteLine("Retrying {0}", retryCount);
                     retry = true;
                     continue;
                 }
                 throw;
             }
             catch (Exception e)
             {
                 throw new ScanDriverUnknownException(e);
             }
             if (image != null)
             {
                 yield return(image);
             }
         } while (retry || (!cancel && ScanProfile.PaperSource != ScanSource.Glass));
     }
 }
Пример #6
0
 private ScannedImage TransferImage(WiaBackgroundEventLoop eventLoop, int pageNumber, out bool cancel)
 {
     try
     {
         // TODO: Use the NoUI flag uniformly
         var transfer = ScanParams.NoUI ? new ConsoleWiaTransfer() : wiaTransfer;
         using (var stream = transfer.Transfer(pageNumber, eventLoop, WiaApi.Formats.BMP))
         {
             if (stream == null)
             {
                 cancel = true;
                 return(null);
             }
             cancel = false;
             using (Image output = Image.FromStream(stream))
             {
                 using (var result = ScannedImageHelper.PostProcessStep1(output, ScanProfile))
                 {
                     if (blankDetector.ExcludePage(result, ScanProfile))
                     {
                         return(null);
                     }
                     ScanBitDepth bitDepth = ScanProfile.UseNativeUI ? ScanBitDepth.C24Bit : ScanProfile.BitDepth;
                     var          image    = new ScannedImage(result, bitDepth, ScanProfile.MaxQuality, ScanProfile.Quality);
                     image.SetThumbnail(thumbnailRenderer.RenderThumbnail(result));
                     ScannedImageHelper.PostProcessStep2(image, ScanProfile, pageNumber);
                     return(image);
                 }
             }
         }
     }
     catch (NoPagesException)
     {
         if (ScanProfile.PaperSource != ScanSource.Glass && pageNumber == 1)
         {
             // No pages were in the feeder, so show the user an error
             throw new NoPagesException();
         }
         // At least one page was scanned but now the feeder is empty, so exit normally
         cancel = true;
         return(null);
     }
     catch (ScanDriverException)
     {
         throw;
     }
     catch (Exception e)
     {
         throw new ScanDriverUnknownException(e);
     }
 }
Пример #7
0
        private Stream DoTransfer(int pageNumber, WiaBackgroundEventLoop eventLoop, string format)
        {
            var invoker = (FormBase)DialogParent;

            if (eventLoop.GetSync(wia => wia.Item) == null)
            {
                return(null);
            }
            if (ScanParams.NoUI)
            {
                return(eventLoop.GetSync(wia => WiaApi.Transfer(wia, format, false)));
            }
            if (pageNumber == 1)
            {
                // The only downside of the common dialog is that it steals focus.
                // If this is the first page, then the user has just pressed the scan button, so that's not
                // an issue and we can use it and get the benefits of progress display and immediate cancellation.
                return(ScanParams.Modal
                    ? eventLoop.GetSync(wia => invoker.InvokeGet(() => WiaApi.Transfer(wia, format, true)))
                    : eventLoop.GetSync(wia => WiaApi.Transfer(wia, format, true)));
            }
            // For subsequent pages, we don't want to take focus in case the user has switched applications,
            // so we use the custom form.
            var form       = formFactory.Create <FScanProgress>();
            var waitHandle = new AutoResetEvent(false);

            form.PageNumber = pageNumber;
            form.Transfer   = () => eventLoop.GetSync(wia => WiaApi.Transfer(wia, format, false));
            form.Closed    += (sender, args) => waitHandle.Set();
            if (ScanParams.Modal)
            {
                invoker.Invoke(() => form.ShowDialog(DialogParent));
            }
            else
            {
                invoker.Invoke(() => form.Show(DialogParent));
            }
            waitHandle.WaitOne();
            if (form.Exception != null)
            {
                WiaApi.ThrowDeviceError(form.Exception);
            }
            if (form.DialogResult == DialogResult.Cancel)
            {
                return(null);
            }
            return(form.ImageStream);
        }
Пример #8
0
        private IScannedImage TransferImage(WiaBackgroundEventLoop eventLoop, int pageNumber)
        {
            try
            {
                using (var stream = wiaTransfer.Transfer(pageNumber, eventLoop, WiaApi.Formats.BMP))
                {
                    if (stream == null)
                    {
                        // User cancelled
                        return(null);
                    }
                    using (Image output = Image.FromStream(stream))
                    {
                        double scaleFactor = 1;
                        if (!ScanSettings.UseNativeUI)
                        {
                            scaleFactor = ScanSettings.AfterScanScale.ToIntScaleFactor();
                        }

                        using (var result = ImageScaleHelper.ScaleImage(output, scaleFactor))
                        {
                            ScanBitDepth bitDepth = ScanSettings.UseNativeUI ? ScanBitDepth.C24Bit : ScanSettings.BitDepth;
                            return(scannedImageFactory.Create(result, bitDepth, ScanSettings.MaxQuality));
                        }
                    }
                }
            }
            catch (COMException e)
            {
                if ((uint)e.ErrorCode == WiaApi.Errors.OUT_OF_PAPER)
                {
                    if (ScanSettings.PaperSource != ScanSource.Glass && pageNumber == 1)
                    {
                        throw new NoPagesException();
                    }
                    return(null);
                }
                else if ((uint)e.ErrorCode == WiaApi.Errors.OFFLINE)
                {
                    throw new DeviceOfflineException();
                }
                else
                {
                    throw new ScanDriverUnknownException(e);
                }
            }
        }
Пример #9
0
        protected override IEnumerable <IScannedImage> ScanInternal()
        {
            using (var eventLoop = new WiaBackgroundEventLoop(ScanSettings, ScanDevice))
            {
                bool supportsFeeder = eventLoop.GetSync(wia => WiaApi.DeviceSupportsFeeder(wia.Device));
                if (ScanSettings.PaperSource != ScanSource.Glass && !supportsFeeder)
                {
                    throw new NoFeederSupportException();
                }
                int pageNumber = 1;
                while (true)
                {
                    bool feederReady = eventLoop.GetSync(wia => WiaApi.DeviceFeederReady(wia.Device));
                    if (ScanSettings.PaperSource != ScanSource.Glass && !feederReady)
                    {
                        if (pageNumber == 1)
                        {
                            throw new NoPagesException();
                        }
                        break;
                    }
                    IScannedImage image;
                    try
                    {
                        image = TransferImage(eventLoop, pageNumber++);
                    }
                    catch (ScanDriverException)
                    {
                        throw;
                    }
                    catch (Exception e)
                    {
                        throw new ScanDriverUnknownException(e);
                    }
                    if (image == null)
                    {
                        break;
                    }
                    yield return(image);

                    if (ScanSettings.PaperSource == ScanSource.Glass)
                    {
                        break;
                    }
                }
            }
        }
Пример #10
0
        private async Task <(ScannedImage, bool)> TransferImage(WiaBackgroundEventLoop eventLoop, int pageNumber)
        {
            return(await Task.Factory.StartNew(() =>
            {
                try
                {
                    ChaosMonkey.MaybeError(0, new COMException("Fail", -2147467259));
                    using (var stream = DoTransfer(pageNumber, eventLoop, WiaApi.Formats.BMP))
                    {
                        if (stream == null)
                        {
                            return (null, true);
                        }

                        using (Image output = Image.FromStream(stream))
                        {
                            using (var result = scannedImageHelper.PostProcessStep1(output, ScanProfile))
                            {
                                if (blankDetector.ExcludePage(result, ScanProfile))
                                {
                                    return (null, false);
                                }

                                ScanBitDepth bitDepth = ScanProfile.UseNativeUI ? ScanBitDepth.C24Bit : ScanProfile.BitDepth;
                                var image = new ScannedImage(result, bitDepth, ScanProfile.MaxQuality, ScanProfile.Quality);
                                scannedImageHelper.PostProcessStep2(image, result, ScanProfile, ScanParams, pageNumber);
                                string tempPath = scannedImageHelper.SaveForBackgroundOcr(result, ScanParams);
                                scannedImageHelper.RunBackgroundOcr(image, ScanParams, tempPath);
                                return (image, false);
                            }
                        }
                    }
                }
                catch (NoPagesException)
                {
                    if (ScanProfile.PaperSource != ScanSource.Glass && pageNumber == 1)
                    {
                        // No pages were in the feeder, so show the user an error
                        throw new NoPagesException();
                    }

                    // At least one page was scanned but now the feeder is empty, so exit normally
                    return (null, true);
                }
            }, TaskCreationOptions.LongRunning));
        }
Пример #11
0
 protected override IEnumerable <ScannedImage> ScanInternal()
 {
     using (var eventLoop = new WiaBackgroundEventLoop(ScanProfile, ScanDevice, threadFactory))
     {
         bool supportsFeeder = eventLoop.GetSync(wia => WiaApi.DeviceSupportsFeeder(wia.Device));
         if (ScanProfile.PaperSource != ScanSource.Glass && !supportsFeeder)
         {
             throw new NoFeederSupportException();
         }
         bool supportsDuplex = eventLoop.GetSync(wia => WiaApi.DeviceSupportsDuplex(wia.Device));
         if (ScanProfile.PaperSource == ScanSource.Duplex && !supportsDuplex)
         {
             throw new NoDuplexSupportException();
         }
         int  pageNumber = 1;
         bool cancel;
         do
         {
             ScannedImage image;
             try
             {
                 image = TransferImage(eventLoop, pageNumber++, out cancel);
             }
             catch (ScanDriverException)
             {
                 throw;
             }
             catch (Exception e)
             {
                 throw new ScanDriverUnknownException(e);
             }
             if (image != null)
             {
                 yield return(image);
             }
         } while (!cancel && ScanProfile.PaperSource != ScanSource.Glass);
     }
 }