Sane scan progress

This commit is contained in:
Ben Olden-Cooligan 2018-08-20 00:42:35 -04:00
parent ae1be83e5e
commit f665d0a3da
4 changed files with 86 additions and 25 deletions

View File

@ -1,9 +1,12 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using NAPS2.Scan.Exceptions;
using NAPS2.Scan.Images;
using NAPS2.Util;
using NAPS2.WinForms;
namespace NAPS2.Scan.Sane
@ -52,20 +55,48 @@ namespace NAPS2.Scan.Sane
protected override IEnumerable<ScannedImage> ScanInternal()
{
// TODO: Support ADF
using (Bitmap output = saneWrapper.ScanOne(ScanDevice.ID, ScanProfile.KeyValueOptions))
yield return Transfer();
}
private ScannedImage Transfer()
{
Stream stream;
if (ScanParams.NoUI)
{
using (var result = scannedImageHelper.PostProcessStep1(output, ScanProfile))
stream = saneWrapper.ScanOne(ScanDevice.ID, ScanProfile.KeyValueOptions, null);
}
else
{
var form = formFactory.Create<FScanProgress>();
form.Transfer = () => saneWrapper.ScanOne(ScanDevice.ID, ScanProfile.KeyValueOptions, form.OnProgress);
form.Show();
if (form.Exception != null)
{
if (blankDetector.ExcludePage(result, ScanProfile))
{
yield break;
}
// TODO: Set bit depth correctly
var image = new ScannedImage(result, ScanProfile.BitDepth, ScanProfile.MaxQuality, ScanProfile.Quality);
image.SetThumbnail(thumbnailRenderer.RenderThumbnail(result));
scannedImageHelper.PostProcessStep2(image, result, ScanProfile, ScanParams, 1);
yield return image;
form.Exception.PreserveStackTrace();
throw form.Exception;
}
if (form.DialogResult == DialogResult.Cancel)
{
return null;
}
stream = form.ImageStream;
}
using (stream)
using (var output = Image.FromStream(stream))
using (var result = scannedImageHelper.PostProcessStep1(output, ScanProfile))
{
if (blankDetector.ExcludePage(result, ScanProfile))
{
return null;
}
// TODO: Set bit depth correctly
var image = new ScannedImage(result, ScanProfile.BitDepth, ScanProfile.MaxQuality, ScanProfile.Quality);
image.SetThumbnail(thumbnailRenderer.RenderThumbnail(result));
scannedImageHelper.PostProcessStep2(image, result, ScanProfile, ScanParams, 1);
return image;
}
}
}

View File

@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using NAPS2.Util;
namespace NAPS2.Scan.Sane
{
@ -10,6 +12,8 @@ namespace NAPS2.Scan.Sane
{
private const string SCANIMAGE = "scanimage";
private readonly Regex ProgressRegex = new Regex(@"^Progress: (\d+(\.\d+)?)%");
public IEnumerable<ScanDevice> GetDeviceList()
{
var proc = StartProcess(SCANIMAGE, @"-f %d|%m%n");
@ -25,12 +29,26 @@ namespace NAPS2.Scan.Sane
}
}
public Bitmap ScanOne(string deviceId, KeyValueScanOptions options)
public Stream ScanOne(string deviceId, KeyValueScanOptions options, ProgressHandler progressCallback)
{
var profileOptions = options == null ? "" : string.Join("", options.Select(kvp => $@" {kvp.Key} ""{kvp.Value.Replace("\"", "\\\"")}"""));
var allOptions = $@"-d ""{deviceId}"" --format=tiff --progress{profileOptions}";
var proc = StartProcess(SCANIMAGE, allOptions);
return new Bitmap(proc.StandardOutput.BaseStream);
proc.ErrorDataReceived += (sender, args) =>
{
if (args.Data != null)
{
var match = ProgressRegex.Match(args.Data);
if (match.Success)
{
progressCallback?.Invoke((int)float.Parse(match.Groups[1].Value) * 10, 1000);
}
}
};
proc.BeginErrorReadLine();
var outputStream = new MemoryStream();
proc.StandardOutput.BaseStream.CopyTo(outputStream);
return outputStream;
}
private static Process StartProcess(string fileName, string args)
@ -47,10 +65,8 @@ namespace NAPS2.Scan.Sane
RedirectStandardOutput = true,
RedirectStandardError = true
},
// EnableRaisingEvents = true
EnableRaisingEvents = true
};
proc.OutputDataReceived += (sender, eventArgs) => Debug.WriteLine("o: " + eventArgs.Data);
proc.ErrorDataReceived += (sender, eventArgs) => Debug.WriteLine("e: " + eventArgs.Data);
proc.Start();
return proc;
}

View File

@ -33,8 +33,7 @@ namespace NAPS2.Scan.Wia
// so we use the custom form.
var form = formFactory.Create<FScanProgress>();
form.PageNumber = pageNumber;
form.EventLoop = eventLoop;
form.Format = format;
form.Transfer = () => eventLoop.GetSync(wia => WiaApi.Transfer(wia, format, false));
form.ShowDialog();
if (form.Exception != null)
{

View File

@ -1,33 +1,48 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using NAPS2.Lang.Resources;
using NAPS2.Scan.Wia;
using NAPS2.Util;
namespace NAPS2.WinForms
{
public partial class FScanProgress : FormBase
{
private readonly ThreadFactory threadFactory;
private bool isComplete;
private bool cancel;
public FScanProgress()
public FScanProgress(ThreadFactory threadFactory)
{
this.threadFactory = threadFactory;
InitializeComponent();
}
public int PageNumber { get; set; }
public WiaBackgroundEventLoop EventLoop { get; set; }
public string Format { get; set; }
public Func<Stream> Transfer { get; set; }
public Stream ImageStream { get; private set; }
public Exception Exception { get; private set; }
public bool OnProgress(int current, int max)
{
SafeInvoke(() =>
{
progressBar.Style = ProgressBarStyle.Continuous;
progressBar.Maximum = max;
progressBar.Value = current;
});
return !cancel;
}
protected override void OnLoad(object sender, EventArgs eventArgs)
{
new LayoutManager(this)
@ -44,11 +59,11 @@ namespace NAPS2.WinForms
private void FScanProgress_Shown(object sender, EventArgs e)
{
EventLoop.DoAsync(wia =>
threadFactory.StartThread(() =>
{
try
{
ImageStream = WiaApi.Transfer(wia, Format, false);
ImageStream = Transfer();
}
catch (Exception ex)
{