mirror of
https://github.com/soukoku/ntwain.git
synced 2025-11-24 16:53:24 +08:00
Some more QoL and sample process options.
This commit is contained in:
67
samples/WinForm32/Form1.Designer.cs
generated
67
samples/WinForm32/Form1.Designer.cs
generated
@@ -41,6 +41,9 @@
|
|||||||
lblState = new System.Windows.Forms.Label();
|
lblState = new System.Windows.Forms.Label();
|
||||||
label3 = new System.Windows.Forms.Label();
|
label3 = new System.Windows.Forms.Label();
|
||||||
btnOpenDef = new System.Windows.Forms.Button();
|
btnOpenDef = new System.Windows.Forms.Button();
|
||||||
|
btnOpenFolder = new System.Windows.Forms.Button();
|
||||||
|
ckSystemDrawing = new System.Windows.Forms.CheckBox();
|
||||||
|
ckBgImageHandling = new System.Windows.Forms.CheckBox();
|
||||||
ckShowUI = new System.Windows.Forms.CheckBox();
|
ckShowUI = new System.Windows.Forms.CheckBox();
|
||||||
capListView = new System.Windows.Forms.ListView();
|
capListView = new System.Windows.Forms.ListView();
|
||||||
colCap = new System.Windows.Forms.ColumnHeader();
|
colCap = new System.Windows.Forms.ColumnHeader();
|
||||||
@@ -53,7 +56,7 @@
|
|||||||
btnStart = new System.Windows.Forms.Button();
|
btnStart = new System.Windows.Forms.Button();
|
||||||
btnShowSettings = new System.Windows.Forms.Button();
|
btnShowSettings = new System.Windows.Forms.Button();
|
||||||
btnClose = new System.Windows.Forms.Button();
|
btnClose = new System.Windows.Forms.Button();
|
||||||
ckBgImageHandling = new System.Windows.Forms.CheckBox();
|
ckSaveDisk = new System.Windows.Forms.CheckBox();
|
||||||
((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
|
((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
|
||||||
splitContainer1.Panel1.SuspendLayout();
|
splitContainer1.Panel1.SuspendLayout();
|
||||||
splitContainer1.Panel2.SuspendLayout();
|
splitContainer1.Panel2.SuspendLayout();
|
||||||
@@ -168,6 +171,9 @@
|
|||||||
//
|
//
|
||||||
// splitContainer1.Panel2
|
// splitContainer1.Panel2
|
||||||
//
|
//
|
||||||
|
splitContainer1.Panel2.Controls.Add(ckSaveDisk);
|
||||||
|
splitContainer1.Panel2.Controls.Add(btnOpenFolder);
|
||||||
|
splitContainer1.Panel2.Controls.Add(ckSystemDrawing);
|
||||||
splitContainer1.Panel2.Controls.Add(ckBgImageHandling);
|
splitContainer1.Panel2.Controls.Add(ckBgImageHandling);
|
||||||
splitContainer1.Panel2.Controls.Add(ckShowUI);
|
splitContainer1.Panel2.Controls.Add(ckShowUI);
|
||||||
splitContainer1.Panel2.Controls.Add(capListView);
|
splitContainer1.Panel2.Controls.Add(capListView);
|
||||||
@@ -209,6 +215,38 @@
|
|||||||
btnOpenDef.UseVisualStyleBackColor = true;
|
btnOpenDef.UseVisualStyleBackColor = true;
|
||||||
btnOpenDef.Click += btnOpenDef_Click;
|
btnOpenDef.Click += btnOpenDef_Click;
|
||||||
//
|
//
|
||||||
|
// btnOpenFolder
|
||||||
|
//
|
||||||
|
btnOpenFolder.Location = new System.Drawing.Point(512, 106);
|
||||||
|
btnOpenFolder.Name = "btnOpenFolder";
|
||||||
|
btnOpenFolder.Size = new System.Drawing.Size(147, 23);
|
||||||
|
btnOpenFolder.TabIndex = 13;
|
||||||
|
btnOpenFolder.Text = "Open saved folder";
|
||||||
|
btnOpenFolder.UseVisualStyleBackColor = true;
|
||||||
|
btnOpenFolder.Click += btnOpenFolder_Click;
|
||||||
|
//
|
||||||
|
// ckSystemDrawing
|
||||||
|
//
|
||||||
|
ckSystemDrawing.AutoSize = true;
|
||||||
|
ckSystemDrawing.Location = new System.Drawing.Point(512, 58);
|
||||||
|
ckSystemDrawing.Name = "ckSystemDrawing";
|
||||||
|
ckSystemDrawing.Size = new System.Drawing.Size(209, 19);
|
||||||
|
ckSystemDrawing.TabIndex = 11;
|
||||||
|
ckSystemDrawing.Text = "Use System.Drawing to save image";
|
||||||
|
ckSystemDrawing.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// ckBgImageHandling
|
||||||
|
//
|
||||||
|
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;
|
||||||
|
//
|
||||||
// ckShowUI
|
// ckShowUI
|
||||||
//
|
//
|
||||||
ckShowUI.AutoSize = true;
|
ckShowUI.AutoSize = true;
|
||||||
@@ -226,10 +264,10 @@
|
|||||||
capListView.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
capListView.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||||
capListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { colCap, colType, colCur, colDef, colExtended, colSupport });
|
capListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { colCap, colType, colCur, colDef, colExtended, colSupport });
|
||||||
capListView.FullRowSelect = true;
|
capListView.FullRowSelect = true;
|
||||||
capListView.Location = new System.Drawing.Point(11, 87);
|
capListView.Location = new System.Drawing.Point(11, 135);
|
||||||
capListView.MultiSelect = false;
|
capListView.MultiSelect = false;
|
||||||
capListView.Name = "capListView";
|
capListView.Name = "capListView";
|
||||||
capListView.Size = new System.Drawing.Size(771, 462);
|
capListView.Size = new System.Drawing.Size(771, 414);
|
||||||
capListView.TabIndex = 8;
|
capListView.TabIndex = 8;
|
||||||
capListView.UseCompatibleStateImageBehavior = false;
|
capListView.UseCompatibleStateImageBehavior = false;
|
||||||
capListView.View = System.Windows.Forms.View.Details;
|
capListView.View = System.Windows.Forms.View.Details;
|
||||||
@@ -267,7 +305,7 @@
|
|||||||
// label4
|
// label4
|
||||||
//
|
//
|
||||||
label4.AutoSize = true;
|
label4.AutoSize = true;
|
||||||
label4.Location = new System.Drawing.Point(13, 62);
|
label4.Location = new System.Drawing.Point(11, 110);
|
||||||
label4.Name = "label4";
|
label4.Name = "label4";
|
||||||
label4.Size = new System.Drawing.Size(91, 15);
|
label4.Size = new System.Drawing.Size(91, 15);
|
||||||
label4.TabIndex = 7;
|
label4.TabIndex = 7;
|
||||||
@@ -303,17 +341,15 @@
|
|||||||
btnClose.UseVisualStyleBackColor = true;
|
btnClose.UseVisualStyleBackColor = true;
|
||||||
btnClose.Click += btnClose_Click;
|
btnClose.Click += btnClose_Click;
|
||||||
//
|
//
|
||||||
// ckBgImageHandling
|
// ckSaveDisk
|
||||||
//
|
//
|
||||||
ckBgImageHandling.AutoSize = true;
|
ckSaveDisk.AutoSize = true;
|
||||||
ckBgImageHandling.Checked = true;
|
ckSaveDisk.Location = new System.Drawing.Point(512, 83);
|
||||||
ckBgImageHandling.CheckState = System.Windows.Forms.CheckState.Checked;
|
ckSaveDisk.Name = "ckSaveDisk";
|
||||||
ckBgImageHandling.Location = new System.Drawing.Point(512, 35);
|
ckSaveDisk.Size = new System.Drawing.Size(88, 19);
|
||||||
ckBgImageHandling.Name = "ckBgImageHandling";
|
ckSaveDisk.TabIndex = 12;
|
||||||
ckBgImageHandling.Size = new System.Drawing.Size(220, 19);
|
ckSaveDisk.Text = "Save to disk";
|
||||||
ckBgImageHandling.TabIndex = 10;
|
ckSaveDisk.UseVisualStyleBackColor = true;
|
||||||
ckBgImageHandling.Text = "Handle image data in another thread";
|
|
||||||
ckBgImageHandling.UseVisualStyleBackColor = true;
|
|
||||||
//
|
//
|
||||||
// Form1
|
// Form1
|
||||||
//
|
//
|
||||||
@@ -360,5 +396,8 @@
|
|||||||
private System.Windows.Forms.ColumnHeader colExtended;
|
private System.Windows.Forms.ColumnHeader colExtended;
|
||||||
private System.Windows.Forms.CheckBox ckShowUI;
|
private System.Windows.Forms.CheckBox ckShowUI;
|
||||||
private System.Windows.Forms.CheckBox ckBgImageHandling;
|
private System.Windows.Forms.CheckBox ckBgImageHandling;
|
||||||
|
private System.Windows.Forms.CheckBox ckSystemDrawing;
|
||||||
|
private System.Windows.Forms.Button btnOpenFolder;
|
||||||
|
private System.Windows.Forms.CheckBox ckSaveDisk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@@ -17,10 +18,15 @@ namespace WinFormSample
|
|||||||
{
|
{
|
||||||
public partial class Form1 : Form
|
public partial class Form1 : Form
|
||||||
{
|
{
|
||||||
private TwainAppSession twain;
|
TwainAppSession twain;
|
||||||
private readonly string saveFolder;
|
readonly string saveFolder;
|
||||||
readonly Stopwatch watch = new();
|
readonly Stopwatch watch = new();
|
||||||
private bool _useThreadForImag;
|
readonly ImageCodecInfo _jpegEncoder;
|
||||||
|
readonly EncoderParameters _jpegParameters;
|
||||||
|
readonly int _jpegQuality = 75;
|
||||||
|
bool _useThreadForImag;
|
||||||
|
bool _useSystemDrawing;
|
||||||
|
bool _saveDisk;
|
||||||
|
|
||||||
public Form1()
|
public Form1()
|
||||||
{
|
{
|
||||||
@@ -43,10 +49,15 @@ namespace WinFormSample
|
|||||||
capListView.SetDoubleBufferedAsNeeded();
|
capListView.SetDoubleBufferedAsNeeded();
|
||||||
SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
|
SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
|
||||||
|
|
||||||
saveFolder = Path.Combine(Path.GetTempPath(), "ntwain-sample");
|
saveFolder = Path.Combine(Path.GetTempPath(), "ntwain-sample" + Path.DirectorySeparatorChar);
|
||||||
Directory.CreateDirectory(saveFolder);
|
Directory.CreateDirectory(saveFolder);
|
||||||
|
|
||||||
this.Disposed += Form1_Disposed;
|
this.Disposed += Form1_Disposed;
|
||||||
|
|
||||||
|
|
||||||
|
_jpegParameters = new EncoderParameters(1);
|
||||||
|
_jpegParameters.Param[0] = new EncoderParameter(Encoder.Quality, (long)_jpegQuality);
|
||||||
|
_jpegEncoder = ImageCodecInfo.GetImageEncoders().First(enc => enc.FormatID == ImageFormat.Jpeg.Guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Twain_SourceDisabled(TwainAppSession sender, TW_IDENTITY_LEGACY e)
|
private void Twain_SourceDisabled(TwainAppSession sender, TW_IDENTITY_LEGACY e)
|
||||||
@@ -137,31 +148,62 @@ namespace WinFormSample
|
|||||||
|
|
||||||
private void HandleTransferredData(TransferredEventArgs e)
|
private void HandleTransferredData(TransferredEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
if (e.Data != null)
|
||||||
{
|
{
|
||||||
// example of using some lib to handle image data
|
try
|
||||||
var saveFile = Path.Combine(saveFolder, (DateTime.Now.Ticks / 1000).ToString());
|
|
||||||
using (var img = new ImageMagick.MagickImage(e.Data))
|
|
||||||
{
|
{
|
||||||
if (img.ColorType == ImageMagick.ColorType.Palette)
|
// example of using some lib to handle image data
|
||||||
|
var saveFile = Path.Combine(saveFolder, (DateTime.Now.Ticks / 1000).ToString());
|
||||||
|
|
||||||
|
if (_useSystemDrawing)
|
||||||
{
|
{
|
||||||
// bw or gray
|
using (var img = Image.FromStream(e.Data.AsStream()))
|
||||||
saveFile += ".png";
|
{
|
||||||
|
if (img.PixelFormat == System.Drawing.Imaging.PixelFormat.Format1bppIndexed ||
|
||||||
|
img.PixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
|
||||||
|
{
|
||||||
|
// bw or gray
|
||||||
|
saveFile += ".png";
|
||||||
|
if (_saveDisk) img.Save(saveFile, ImageFormat.Png);
|
||||||
|
else img.Save(new NoOpStream(), ImageFormat.Png);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// color
|
||||||
|
saveFile += ".jpg";
|
||||||
|
if (_saveDisk) img.Save(saveFile, _jpegEncoder, _jpegParameters);
|
||||||
|
else img.Save(new NoOpStream(), _jpegEncoder, _jpegParameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// color
|
using (var img = new ImageMagick.MagickImage(e.Data.AsSpan()))
|
||||||
saveFile += ".jpg";
|
{
|
||||||
img.Quality = 75;
|
var format = ImageMagick.MagickFormat.Png;
|
||||||
|
if (img.ColorType == ImageMagick.ColorType.Palette)
|
||||||
|
{
|
||||||
|
// bw or gray
|
||||||
|
saveFile += ".png";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// color
|
||||||
|
saveFile += ".jpg";
|
||||||
|
format = ImageMagick.MagickFormat.Jpeg;
|
||||||
|
img.Quality = _jpegQuality;
|
||||||
|
}
|
||||||
|
if (_saveDisk) img.Write(saveFile);
|
||||||
|
else img.Write(new NoOpStream(), format);
|
||||||
|
}
|
||||||
|
Debug.WriteLine($"Saved image to {saveFile}");
|
||||||
}
|
}
|
||||||
img.Write(saveFile);
|
|
||||||
Debug.WriteLine($"Saved image to {saveFile}");
|
|
||||||
}
|
}
|
||||||
}
|
catch { }
|
||||||
catch { }
|
finally
|
||||||
finally
|
{
|
||||||
{
|
e.Dispose();
|
||||||
e.Dispose();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,8 +444,20 @@ namespace WinFormSample
|
|||||||
if (twain.EnableSource(ckShowUI.Checked, false).IsSuccess)
|
if (twain.EnableSource(ckShowUI.Checked, false).IsSuccess)
|
||||||
{
|
{
|
||||||
_useThreadForImag = ckBgImageHandling.Checked;
|
_useThreadForImag = ckBgImageHandling.Checked;
|
||||||
|
_useSystemDrawing = ckSystemDrawing.Checked;
|
||||||
|
_saveDisk = ckSaveDisk.Checked;
|
||||||
watch.Restart();
|
watch.Restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void btnOpenFolder_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(saveFolder)) Directory.CreateDirectory(saveFolder);
|
||||||
|
using (Process.Start(new ProcessStartInfo { FileName = saveFolder, UseShellExecute = true })) { }
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
44
samples/WinForm32/NoOpStream.cs
Normal file
44
samples/WinForm32/NoOpStream.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WinFormSample
|
||||||
|
{
|
||||||
|
internal class NoOpStream : Stream
|
||||||
|
{
|
||||||
|
public override bool CanRead => false;
|
||||||
|
|
||||||
|
public override bool CanSeek => false;
|
||||||
|
|
||||||
|
public override bool CanWrite => true;
|
||||||
|
|
||||||
|
public override long Length => 0;
|
||||||
|
|
||||||
|
public override long Position { get => 0; set { } }
|
||||||
|
|
||||||
|
public override void Flush()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Read(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Seek(long offset, SeekOrigin origin)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetLength(long value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace NTwain.Data
|
namespace NTwain.Data
|
||||||
{
|
{
|
||||||
@@ -13,7 +14,7 @@ namespace NTwain.Data
|
|||||||
// so the array max is made with 32 MB. Typical usage should be a lot less.
|
// so the array max is made with 32 MB. Typical usage should be a lot less.
|
||||||
internal static readonly ArrayPool<byte> MemPool = ArrayPool<byte>.Create(32 * 1024 * 1024, 8);
|
internal static readonly ArrayPool<byte> MemPool = ArrayPool<byte>.Create(32 * 1024 * 1024, 8);
|
||||||
|
|
||||||
public BufferedData(int size)
|
internal BufferedData(int size)
|
||||||
{
|
{
|
||||||
_buffer = MemPool.Rent(size);
|
_buffer = MemPool.Rent(size);
|
||||||
_length = size;
|
_length = size;
|
||||||
@@ -27,14 +28,14 @@ namespace NTwain.Data
|
|||||||
_fromPool = fromPool;
|
_fromPool = fromPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _disposed;
|
||||||
bool _fromPool;
|
bool _fromPool;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Bytes buffer. This may be bigger than the data size
|
/// Bytes buffer. This may be bigger than the data size
|
||||||
/// and contain invalid data.
|
/// and contain invalid data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
byte[]? _buffer;
|
byte[] _buffer;
|
||||||
public byte[]? Buffer { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Actual usable data length in the buffer.
|
/// Actual usable data length in the buffer.
|
||||||
@@ -45,19 +46,47 @@ namespace NTwain.Data
|
|||||||
/// As a span of usable data.
|
/// As a span of usable data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
/// <exception cref="ObjectDisposedException"></exception>
|
||||||
public ReadOnlySpan<byte> AsSpan()
|
public ReadOnlySpan<byte> AsSpan()
|
||||||
{
|
{
|
||||||
if (_buffer != null) return _buffer.AsSpan(0, _length);
|
if (_disposed) throw new ObjectDisposedException(GetType().FullName);
|
||||||
return Span<byte>.Empty;
|
return _buffer.AsSpan(0, _length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// As a span of usable data.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="ObjectDisposedException"></exception>
|
||||||
|
public ReadOnlyMemory<byte> AsMemory()
|
||||||
|
{
|
||||||
|
if (_disposed) throw new ObjectDisposedException(GetType().FullName);
|
||||||
|
return _buffer.AsMemory(0, _length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// As a readonly stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="ObjectDisposedException"></exception>
|
||||||
|
public Stream AsStream()
|
||||||
|
{
|
||||||
|
if (_disposed) throw new ObjectDisposedException(GetType().FullName);
|
||||||
|
return new MemoryStream(_buffer, 0, _length, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (_fromPool && _buffer != null)
|
if (_fromPool && _disposed)
|
||||||
{
|
{
|
||||||
MemPool.Return(_buffer);
|
MemPool.Return(_buffer);
|
||||||
_buffer = null;
|
_disposed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static implicit operator ReadOnlySpan<byte>(BufferedData value) => value.AsSpan();
|
||||||
|
public static implicit operator ReadOnlyMemory<byte>(BufferedData value) => value.AsMemory();
|
||||||
|
public static implicit operator Stream(BufferedData value) => value.AsStream();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace NTwain
|
|||||||
/// IMPORTANT: Content of this array will not be valid once
|
/// IMPORTANT: Content of this array will not be valid once
|
||||||
/// this event arg has been disposed.
|
/// this event arg has been disposed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlySpan<byte> Data => _data == null ? ReadOnlySpan<byte>.Empty : _data.AsSpan();
|
public BufferedData? Data => _data;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The file info if the transfer involved file information.
|
/// The file info if the transfer involved file information.
|
||||||
|
|||||||
Reference in New Issue
Block a user