mirror of
https://github.com/soukoku/ntwain.git
synced 2026-02-25 13:04:07 +08:00
Added possibility to handle transferred data by app in another thread for high-speed scanner use.
This commit is contained in:
37
samples/WinForm32/Form1.Designer.cs
generated
37
samples/WinForm32/Form1.Designer.cs
generated
@@ -41,6 +41,7 @@
|
||||
lblState = new System.Windows.Forms.Label();
|
||||
label3 = new System.Windows.Forms.Label();
|
||||
btnOpenDef = new System.Windows.Forms.Button();
|
||||
ckShowUI = new System.Windows.Forms.CheckBox();
|
||||
capListView = new System.Windows.Forms.ListView();
|
||||
colCap = new System.Windows.Forms.ColumnHeader();
|
||||
colType = new System.Windows.Forms.ColumnHeader();
|
||||
@@ -52,7 +53,7 @@
|
||||
btnStart = new System.Windows.Forms.Button();
|
||||
btnShowSettings = new System.Windows.Forms.Button();
|
||||
btnClose = new System.Windows.Forms.Button();
|
||||
ckShowUI = new System.Windows.Forms.CheckBox();
|
||||
ckBgImageHandling = new System.Windows.Forms.CheckBox();
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
|
||||
splitContainer1.Panel1.SuspendLayout();
|
||||
splitContainer1.Panel2.SuspendLayout();
|
||||
@@ -167,6 +168,7 @@
|
||||
//
|
||||
// splitContainer1.Panel2
|
||||
//
|
||||
splitContainer1.Panel2.Controls.Add(ckBgImageHandling);
|
||||
splitContainer1.Panel2.Controls.Add(ckShowUI);
|
||||
splitContainer1.Panel2.Controls.Add(capListView);
|
||||
splitContainer1.Panel2.Controls.Add(label4);
|
||||
@@ -207,6 +209,18 @@
|
||||
btnOpenDef.UseVisualStyleBackColor = true;
|
||||
btnOpenDef.Click += btnOpenDef_Click;
|
||||
//
|
||||
// ckShowUI
|
||||
//
|
||||
ckShowUI.AutoSize = true;
|
||||
ckShowUI.Checked = true;
|
||||
ckShowUI.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
ckShowUI.Location = new System.Drawing.Point(437, 35);
|
||||
ckShowUI.Name = "ckShowUI";
|
||||
ckShowUI.Size = new System.Drawing.Size(69, 19);
|
||||
ckShowUI.TabIndex = 9;
|
||||
ckShowUI.Text = "Show UI";
|
||||
ckShowUI.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// capListView
|
||||
//
|
||||
capListView.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
@@ -289,17 +303,17 @@
|
||||
btnClose.UseVisualStyleBackColor = true;
|
||||
btnClose.Click += btnClose_Click;
|
||||
//
|
||||
// ckShowUI
|
||||
// ckBgImageHandling
|
||||
//
|
||||
ckShowUI.AutoSize = true;
|
||||
ckShowUI.Checked = true;
|
||||
ckShowUI.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
ckShowUI.Location = new System.Drawing.Point(437, 35);
|
||||
ckShowUI.Name = "ckShowUI";
|
||||
ckShowUI.Size = new System.Drawing.Size(69, 19);
|
||||
ckShowUI.TabIndex = 9;
|
||||
ckShowUI.Text = "Show UI";
|
||||
ckShowUI.UseVisualStyleBackColor = true;
|
||||
ckBgImageHandling.AutoSize = true;
|
||||
ckBgImageHandling.Checked = true;
|
||||
ckBgImageHandling.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
ckBgImageHandling.Location = new System.Drawing.Point(512, 35);
|
||||
ckBgImageHandling.Name = "ckBgImageHandling";
|
||||
ckBgImageHandling.Size = new System.Drawing.Size(220, 19);
|
||||
ckBgImageHandling.TabIndex = 10;
|
||||
ckBgImageHandling.Text = "Handle image data in another thread";
|
||||
ckBgImageHandling.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
@@ -345,5 +359,6 @@
|
||||
private System.Windows.Forms.ColumnHeader colSupport;
|
||||
private System.Windows.Forms.ColumnHeader colExtended;
|
||||
private System.Windows.Forms.CheckBox ckShowUI;
|
||||
private System.Windows.Forms.CheckBox ckBgImageHandling;
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,11 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace WinFormSample
|
||||
@@ -20,6 +19,8 @@ namespace WinFormSample
|
||||
{
|
||||
private TwainAppSession twain;
|
||||
private readonly string saveFolder;
|
||||
readonly Stopwatch watch = new();
|
||||
private bool _useThreadForImag;
|
||||
|
||||
public Form1()
|
||||
{
|
||||
@@ -33,8 +34,9 @@ namespace WinFormSample
|
||||
twain.StateChanged += Twain_StateChanged;
|
||||
twain.DefaultSourceChanged += Twain_DefaultSourceChanged;
|
||||
twain.CurrentSourceChanged += Twain_CurrentSourceChanged;
|
||||
twain.SourceDisabled += Twain_SourceDisabled;
|
||||
twain.TransferReady += Twain_TransferReady;
|
||||
twain.Transferred += Twain_DataTransferred;
|
||||
twain.Transferred += Twain_Transferred;
|
||||
twain.TransferError += Twain_TransferError;
|
||||
twain.DeviceEvent += Twain_DeviceEvent;
|
||||
|
||||
@@ -47,6 +49,15 @@ namespace WinFormSample
|
||||
this.Disposed += Form1_Disposed;
|
||||
}
|
||||
|
||||
private void Twain_SourceDisabled(TwainAppSession sender, TW_IDENTITY_LEGACY e)
|
||||
{
|
||||
if (watch.IsRunning)
|
||||
{
|
||||
watch.Stop();
|
||||
MessageBox.Show($"Took {watch.Elapsed} to finish that transfer.");
|
||||
}
|
||||
}
|
||||
|
||||
private void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
|
||||
{
|
||||
switch (e.Reason)
|
||||
@@ -103,28 +114,54 @@ namespace WinFormSample
|
||||
|
||||
}
|
||||
|
||||
private void Twain_DataTransferred(TwainAppSession sender, TransferredEventArgs e)
|
||||
private void Twain_Transferred(TwainAppSession sender, TransferredEventArgs e)
|
||||
{
|
||||
Debug.WriteLine($"[thread {Environment.CurrentManagedThreadId}] data transferred with info {e.ImageInfo}");
|
||||
if (e.Data == null) return;
|
||||
// if using a high-speed scanner, imaging handling could be a bottleneck
|
||||
// so it's possible to pass the data to another thread while the scanning
|
||||
// loop happens. Just remember to dispose it after.
|
||||
|
||||
// example of using some lib to handle image data
|
||||
var saveFile = Path.Combine(saveFolder, (DateTime.Now.Ticks / 1000).ToString());
|
||||
using (var img = new ImageMagick.MagickImage(e.Data))
|
||||
if (_useThreadForImag)
|
||||
{
|
||||
if (img.ColorType == ImageMagick.ColorType.Palette)
|
||||
// bad thread example but whatev. should use a dedicated thread of some sort for real
|
||||
Task.Run(() =>
|
||||
{
|
||||
// bw or gray
|
||||
saveFile += ".png";
|
||||
}
|
||||
else
|
||||
HandleTransferredData(e);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleTransferredData(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleTransferredData(TransferredEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// example of using some lib to handle image data
|
||||
var saveFile = Path.Combine(saveFolder, (DateTime.Now.Ticks / 1000).ToString());
|
||||
using (var img = new ImageMagick.MagickImage(e.Data))
|
||||
{
|
||||
// color
|
||||
saveFile += ".jpg";
|
||||
img.Quality = 75;
|
||||
if (img.ColorType == ImageMagick.ColorType.Palette)
|
||||
{
|
||||
// bw or gray
|
||||
saveFile += ".png";
|
||||
}
|
||||
else
|
||||
{
|
||||
// color
|
||||
saveFile += ".jpg";
|
||||
img.Quality = 75;
|
||||
}
|
||||
img.Write(saveFile);
|
||||
Debug.WriteLine($"Saved image to {saveFile}");
|
||||
}
|
||||
img.Write(saveFile);
|
||||
Debug.WriteLine($"Saved image to {saveFile}");
|
||||
}
|
||||
catch { }
|
||||
finally
|
||||
{
|
||||
e.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,7 +399,11 @@ namespace WinFormSample
|
||||
|
||||
private void btnStart_Click(object sender, EventArgs e)
|
||||
{
|
||||
twain.EnableSource(ckShowUI.Checked, false);
|
||||
if (twain.EnableSource(ckShowUI.Checked, false).IsSuccess)
|
||||
{
|
||||
_useThreadForImag = ckBgImageHandling.Checked;
|
||||
watch.Restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user