コード例 #1
0
        private async Task <(ScannedImage, bool)> Transfer(Lazy <KeyValueScanOptions> options, int pageNumber)
        {
            return(await Task.Factory.StartNew(() =>
            {
                Stream stream;
                if (ScanParams.NoUi)
                {
                    stream = saneWrapper.ScanOne(ScanDevice.Id, options.Value, null, CancelToken);
                }
                else
                {
                    var form = formFactory.Create <FScanProgress>();
                    var unifiedCancelToken = CancellationTokenSource.CreateLinkedTokenSource(form.CancelToken, CancelToken).Token;
                    form.Transfer = () => saneWrapper.ScanOne(ScanDevice.Id, options.Value, form.OnProgress, unifiedCancelToken);
                    form.PageNumber = pageNumber;
                    ((FormBase)Application.OpenForms[0]).SafeInvoke(() => form.ShowDialog());

                    if (form.Exception != null)
                    {
                        form.Exception.PreserveStackTrace();
                        throw form.Exception;
                    }
                    if (form.DialogResult == DialogResult.Cancel)
                    {
                        return (null, true);
                    }

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

                            // By converting to 1bpp here we avoid the Win32 call in the BitmapHelper conversion
                            // This converter also has the side effect of working even if the scanner doesn't support Lineart
                            using (var encoded = ScanProfile.BitDepth == ScanBitDepth.BlackWhite ? UnsafeImageOps.ConvertTo1Bpp(result, -ScanProfile.Brightness) : result)
                            {
                                var image = new ScannedImage(encoded, ScanProfile.BitDepth, ScanProfile.MaxQuality, ScanProfile.Quality);
                                scannedImageHelper.PostProcessStep2(image, result, ScanProfile, ScanParams, 1, false);
                                var tempPath = scannedImageHelper.SaveForBackgroundOcr(result, ScanParams);
                                scannedImageHelper.RunBackgroundOcr(image, ScanParams, tempPath);
                                return (image, false);
                            }
                        }
            }, TaskCreationOptions.LongRunning));
        }
コード例 #2
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);
     }
 }
コード例 #3
0
ファイル: WiaScanDriver.cs プロジェクト: pnoble04/naps2
        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));
        }
コード例 #4
0
ファイル: WiaScanOperation.cs プロジェクト: damieng/naps2
        private void ProduceImage(ScannedImageSource.Concrete source, Image output, ref int pageNumber)
        {
            var results = new[] { scannedImageHelper.PostProcessStep1(output, ScanProfile) };

            if (ScanProfile.DivideScanIntoTwoPages)
            {
                var result = results[0];

                // Should probably detect portrait vs landscape and split appropriately but this is the
                // main use case.
                var halfHeight = result.Height / 2;
                var firstRect  = new Rectangle(0, 0, result.Width, halfHeight);
                var secondRect = new Rectangle(0, halfHeight, result.Width, halfHeight);

                var firstPage = result.Clone(secondRect, result.PixelFormat);
                firstPage.RotateFlip(RotateFlipType.Rotate90FlipNone);
                var secondPage = result.Clone(firstRect, result.PixelFormat);
                secondPage.RotateFlip(RotateFlipType.Rotate90FlipNone);

                results = new[] { firstPage, secondPage };

                result.Dispose();
            }

            foreach (var result in results)
            {
                if (blankDetector.ExcludePage(result, ScanProfile))
                {
                    continue;
                }

                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);
                result.Dispose();
                scannedImageHelper.RunBackgroundOcr(image, ScanParams, tempPath);
                source.Put(image);

                pageNumber++;
                InitNextPageProgress(pageNumber);
            }
        }
コード例 #5
0
ファイル: WiaScanOperation.cs プロジェクト: yogvirus/naps2
        private void ProduceImage(ScannedImageSource.Concrete source, Image output, ref int pageNumber)
        {
            using (var result = scannedImageHelper.PostProcessStep1(output, ScanProfile))
            {
                if (blankDetector.ExcludePage(result, ScanProfile))
                {
                    return;
                }

                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);
                source.Put(image);

                pageNumber++;
                InitNextPageProgress(pageNumber);
            }
        }
コード例 #6
0
ファイル: TwainWrapper.cs プロジェクト: twingo999/naps2
        public List <ScannedImage> Scan(IWin32Window dialogParent, bool activate, ScanDevice scanDevice, ScanProfile scanProfile, ScanParams scanParams)
        {
            if (scanProfile.TwainImpl == TwainImpl.Legacy)
            {
                return(Legacy.TwainApi.Scan(scanProfile, scanDevice, dialogParent, formFactory));
            }

            PlatformInfo.Current.PreferNewDSM = scanProfile.TwainImpl != TwainImpl.OldDsm;
            var        session   = new TwainSession(TwainAppId);
            var        twainForm = formFactory.Create <FTwainGui>();
            var        images    = new List <ScannedImage>();
            Exception  error     = null;
            bool       cancel    = false;
            DataSource ds        = null;

            int pageNumber = 0;

            session.TransferReady += (sender, eventArgs) =>
            {
                Debug.WriteLine("NAPS2.TW - TransferReady");
                if (cancel)
                {
                    eventArgs.CancelAll = true;
                }
            };
            session.DataTransferred += (sender, eventArgs) =>
            {
                try
                {
                    Debug.WriteLine("NAPS2.TW - DataTransferred");
                    pageNumber++;
                    using (var output = scanProfile.TwainImpl == TwainImpl.MemXfer
                                        ? GetBitmapFromMemXFer(eventArgs.MemoryData, eventArgs.ImageInfo)
                                        : Image.FromStream(eventArgs.GetNativeImageStream()))
                    {
                        using (var result = scannedImageHelper.PostProcessStep1(output, scanProfile))
                        {
                            if (blankDetector.ExcludePage(result, scanProfile))
                            {
                                return;
                            }

                            var bitDepth = output.PixelFormat == PixelFormat.Format1bppIndexed
                                ? ScanBitDepth.BlackWhite
                                : ScanBitDepth.C24Bit;
                            var image = new ScannedImage(result, bitDepth, scanProfile.MaxQuality, scanProfile.Quality);
                            image.SetThumbnail(thumbnailRenderer.RenderThumbnail(result));
                            if (scanParams.DetectPatchCodes)
                            {
                                foreach (var patchCodeInfo in eventArgs.GetExtImageInfo(ExtendedImageInfo.PatchCode))
                                {
                                    if (patchCodeInfo.ReturnCode == ReturnCode.Success)
                                    {
                                        image.PatchCode = GetPatchCode(patchCodeInfo);
                                    }
                                }
                            }
                            scannedImageHelper.PostProcessStep2(image, result, scanProfile, scanParams, pageNumber);
                            images.Add(image);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("NAPS2.TW - DataTransferred - Error");
                    error  = ex;
                    cancel = true;
                    twainForm.Close();
                }
            };
            session.TransferError += (sender, eventArgs) =>
            {
                Debug.WriteLine("NAPS2.TW - TransferError");
                if (eventArgs.Exception != null)
                {
                    error = eventArgs.Exception;
                }
                else if (eventArgs.SourceStatus != null)
                {
                    Log.Error("TWAIN Transfer Error. Return code = {0}; condition code = {1}; data = {2}.",
                              eventArgs.ReturnCode, eventArgs.SourceStatus.ConditionCode, eventArgs.SourceStatus.Data);
                }
                else
                {
                    Log.Error("TWAIN Transfer Error. Return code = {0}.", eventArgs.ReturnCode);
                }
                cancel = true;
                twainForm.Close();
            };
            session.SourceDisabled += (sender, eventArgs) =>
            {
                Debug.WriteLine("NAPS2.TW - SourceDisabled");
                twainForm.Close();
            };

            twainForm.Shown += (sender, eventArgs) =>
            {
                if (activate)
                {
                    // TODO: Set this flag based on whether NAPS2 already has focus
                    // http://stackoverflow.com/questions/7162834/determine-if-current-application-is-activated-has-focus
                    // Or maybe http://stackoverflow.com/questions/156046/show-a-form-without-stealing-focus
                    twainForm.Activate();
                }
                Debug.WriteLine("NAPS2.TW - TwainForm.Shown");
                try
                {
                    ReturnCode rc = session.Open(new WindowsFormsMessageLoopHook(dialogParent.Handle));
                    if (rc != ReturnCode.Success)
                    {
                        Debug.WriteLine("NAPS2.TW - Could not open session - {0}", rc);
                        twainForm.Close();
                        return;
                    }
                    ds = session.FirstOrDefault(x => x.Name == scanDevice.ID);
                    if (ds == null)
                    {
                        Debug.WriteLine("NAPS2.TW - Could not find DS - DS count = {0}", session.Count());
                        throw new DeviceNotFoundException();
                    }
                    rc = ds.Open();
                    if (rc != ReturnCode.Success)
                    {
                        Debug.WriteLine("NAPS2.TW - Could not open DS - {0}", rc);
                        twainForm.Close();
                        return;
                    }
                    ConfigureDS(ds, scanProfile, scanParams);
                    var ui = scanProfile.UseNativeUI ? SourceEnableMode.ShowUI : SourceEnableMode.NoUI;
                    Debug.WriteLine("NAPS2.TW - Enabling DS");
                    rc = ds.Enable(ui, true, twainForm.Handle);
                    Debug.WriteLine("NAPS2.TW - Enable finished");
                    if (rc != ReturnCode.Success)
                    {
                        Debug.WriteLine("NAPS2.TW - Enable failed - {0}, rc");
                        twainForm.Close();
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("NAPS2.TW - Error");
                    error = ex;
                    twainForm.Close();
                }
            };

            Debug.WriteLine("NAPS2.TW - Showing TwainForm");
            twainForm.ShowDialog(dialogParent);
            Debug.WriteLine("NAPS2.TW - TwainForm closed");

            if (ds != null && session.IsSourceOpen)
            {
                Debug.WriteLine("NAPS2.TW - Closing DS");
                ds.Close();
            }
            if (session.IsDsmOpen)
            {
                Debug.WriteLine("NAPS2.TW - Closing session");
                session.Close();
            }

            if (error != null)
            {
                Debug.WriteLine("NAPS2.TW - Throwing error - {0}", error);
                if (error is ScanDriverException)
                {
                    throw error;
                }
                throw new ScanDriverUnknownException(error);
            }

            return(images);
        }
コード例 #7
0
        private void InternalScan(TwainImpl twainImpl, IWin32Window dialogParent, ScanDevice scanDevice, ScanProfile scanProfile, ScanParams scanParams,
                                  CancellationToken cancelToken, ScannedImageSource.Concrete source, Action <ScannedImage, ScanParams, string> runBackgroundOcr)
        {
            if (dialogParent == null)
            {
                dialogParent = new BackgroundForm();
            }
            if (twainImpl == TwainImpl.Legacy)
            {
                Legacy.TwainApi.Scan(scanProfile, scanDevice, dialogParent, formFactory, source);
                return;
            }

            PlatformInfo.Current.PreferNewDSM = twainImpl != TwainImpl.OldDsm;
            var        session    = new TwainSession(TwainAppId);
            var        twainForm  = Invoker.Current.InvokeGet(() => scanParams.NoUI ? null : formFactory.Create <FTwainGui>());
            Exception  error      = null;
            bool       cancel     = false;
            DataSource ds         = null;
            var        waitHandle = new AutoResetEvent(false);

            int pageNumber = 0;

            session.TransferReady += (sender, eventArgs) =>
            {
                Debug.WriteLine("NAPS2.TW - TransferReady");
                if (cancel)
                {
                    eventArgs.CancelAll = true;
                }
            };
            session.DataTransferred += (sender, eventArgs) =>
            {
                try
                {
                    Debug.WriteLine("NAPS2.TW - DataTransferred");
                    pageNumber++;
                    using (var output = twainImpl == TwainImpl.MemXfer
                                        ? GetBitmapFromMemXFer(eventArgs.MemoryData, eventArgs.ImageInfo)
                                        : Image.FromStream(eventArgs.GetNativeImageStream()))
                    {
                        using (var result = scannedImageHelper.PostProcessStep1(output, scanProfile))
                        {
                            if (blankDetector.ExcludePage(result, scanProfile))
                            {
                                return;
                            }

                            var bitDepth = output.PixelFormat == PixelFormat.Format1bppIndexed
                                ? ScanBitDepth.BlackWhite
                                : ScanBitDepth.C24Bit;
                            var image = new ScannedImage(result, bitDepth, scanProfile.MaxQuality, scanProfile.Quality);
                            if (scanParams.DetectPatchCodes)
                            {
                                foreach (var patchCodeInfo in eventArgs.GetExtImageInfo(ExtendedImageInfo.PatchCode))
                                {
                                    if (patchCodeInfo.ReturnCode == ReturnCode.Success)
                                    {
                                        image.PatchCode = GetPatchCode(patchCodeInfo);
                                    }
                                }
                            }
                            scannedImageHelper.PostProcessStep2(image, result, scanProfile, scanParams, pageNumber);
                            string tempPath = scannedImageHelper.SaveForBackgroundOcr(result, scanParams);
                            runBackgroundOcr(image, scanParams, tempPath);
                            source.Put(image);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("NAPS2.TW - DataTransferred - Error");
                    error  = ex;
                    cancel = true;
                    StopTwain();
                }
            };
            session.TransferError += (sender, eventArgs) =>
            {
                Debug.WriteLine("NAPS2.TW - TransferError");
                if (eventArgs.Exception != null)
                {
                    error = eventArgs.Exception;
                }
                else if (eventArgs.SourceStatus != null)
                {
                    Log.Error("TWAIN Transfer Error. Return code = {0}; condition code = {1}; data = {2}.",
                              eventArgs.ReturnCode, eventArgs.SourceStatus.ConditionCode, eventArgs.SourceStatus.Data);
                }
                else
                {
                    Log.Error("TWAIN Transfer Error. Return code = {0}.", eventArgs.ReturnCode);
                }
                cancel = true;
                StopTwain();
            };
            session.SourceDisabled += (sender, eventArgs) =>
            {
                Debug.WriteLine("NAPS2.TW - SourceDisabled");
                StopTwain();
            };

            void StopTwain()
            {
                waitHandle.Set();
                if (!scanParams.NoUI)
                {
                    Invoker.Current.Invoke(() => twainForm.Close());
                }
            }

            void InitTwain()
            {
                try
                {
                    var        windowHandle = (Invoker.Current as Form)?.Handle;
                    ReturnCode rc           = windowHandle != null?session.Open(new WindowsFormsMessageLoopHook(windowHandle.Value)) : session.Open();

                    if (rc != ReturnCode.Success)
                    {
                        Debug.WriteLine("NAPS2.TW - Could not open session - {0}", rc);
                        StopTwain();
                        return;
                    }
                    ds = session.FirstOrDefault(x => x.Name == scanDevice.ID);
                    if (ds == null)
                    {
                        Debug.WriteLine("NAPS2.TW - Could not find DS - DS count = {0}", session.Count());
                        throw new DeviceNotFoundException();
                    }
                    rc = ds.Open();
                    if (rc != ReturnCode.Success)
                    {
                        Debug.WriteLine("NAPS2.TW - Could not open DS - {0}", rc);
                        StopTwain();
                        return;
                    }
                    ConfigureDS(ds, scanProfile, scanParams);
                    var ui = scanProfile.UseNativeUI ? SourceEnableMode.ShowUI : SourceEnableMode.NoUI;
                    Debug.WriteLine("NAPS2.TW - Enabling DS");
                    rc = scanParams.NoUI ? ds.Enable(ui, true, windowHandle ?? IntPtr.Zero) : ds.Enable(ui, true, twainForm.Handle);
                    Debug.WriteLine("NAPS2.TW - Enable finished");
                    if (rc != ReturnCode.Success)
                    {
                        Debug.WriteLine("NAPS2.TW - Enable failed - {0}, rc");
                        StopTwain();
                    }
                    else
                    {
                        cancelToken.Register(() =>
                        {
                            Debug.WriteLine("NAPS2.TW - User Cancel");
                            cancel = true;
                            session.ForceStepDown(5);
                        });
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("NAPS2.TW - Error");
                    error = ex;
                    StopTwain();
                }
            }

            if (!scanParams.NoUI)
            {
                twainForm.Shown  += (sender, eventArgs) => { InitTwain(); };
                twainForm.Closed += (sender, args) => waitHandle.Set();
            }

            if (scanParams.NoUI)
            {
                Debug.WriteLine("NAPS2.TW - Init with no form");
                Invoker.Current.Invoke(InitTwain);
            }
            else if (!scanParams.Modal)
            {
                Debug.WriteLine("NAPS2.TW - Init with non-modal form");
                Invoker.Current.Invoke(() => twainForm.Show(dialogParent));
            }
            else
            {
                Debug.WriteLine("NAPS2.TW - Init with modal form");
                Invoker.Current.Invoke(() => twainForm.ShowDialog(dialogParent));
            }
            waitHandle.WaitOne();
            Debug.WriteLine("NAPS2.TW - Operation complete");

            if (ds != null && session.IsSourceOpen)
            {
                Debug.WriteLine("NAPS2.TW - Closing DS");
                ds.Close();
            }
            if (session.IsDsmOpen)
            {
                Debug.WriteLine("NAPS2.TW - Closing session");
                session.Close();
            }

            if (error != null)
            {
                Debug.WriteLine("NAPS2.TW - Throwing error - {0}", error);
                if (error is ScanDriverException)
                {
                    throw error;
                }
                throw new ScanDriverUnknownException(error);
            }
        }