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; }
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()); }
protected override IEnumerable<IScannedImage> 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; while (true) { 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 (ScanProfile.PaperSource == ScanSource.Glass) { break; } } } }
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); ScannedImageHelper.PostProcessStep2(image, ScanProfile); return image; } } } } catch (COMException e) { if ((uint)e.ErrorCode == WiaApi.Errors.OUT_OF_PAPER) { if (ScanProfile.PaperSource != ScanSource.Glass && pageNumber == 1) { throw new NoPagesException(); } cancel = true; return null; } else if ((uint)e.ErrorCode == WiaApi.Errors.OFFLINE) { throw new DeviceOfflineException(); } else { throw new ScanDriverUnknownException(e); } } }
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)); } }
private ScannedImage TransferImage(WiaBackgroundEventLoop eventLoop, int pageNumber, out bool cancel) { try { var transfer = ScanParams.NoUI ? backgroundWiaTransfer : foregroundWiaTransfer; ChaosMonkey.MaybeError(0.5, new COMException("Fail", -2147467259)); 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, result, ScanProfile, ScanParams, 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); } }
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); } } }