123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- using NTwain;
- using NTwain.Data;
- using PDF_Master.Model;
- using Prism.Commands;
- using Prism.Mvvm;
- using Prism.Services.Dialogs;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Interop;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- namespace PDF_Master.ViewModels.Dialog.HomePageToolsDialogs
- {
- //扫描仪设备
- public class ScannerItem : BindableBase
- {
- public DataSource DataSourceItem { get; set; }
- public ScannerItem(DataSource dataSource)
- {
- DataSourceItem = dataSource;
- ScannerName = dataSource.Name;
- }
- public string ScannerName { get; set; }
- }
- public class CreateFromScannerDialogsViewModel : BindableBase, IDialogAware
- {
- private List<ScannerItem> _scanners = new List<ScannerItem>();
- public List<ScannerItem> Scanners
- {
- get { return _scanners; }
- set => SetProperty(ref _scanners, value);
- }
- //图片
- private ImageSource _img;
- public ImageSource Img
- {
- get { return _img; }
- set => SetProperty(ref _img, value);
- }
- //没有检测到扫描仪
- private bool _isEmptyScanner;
- public bool IsEmptyScanner
- {
- get { return _isEmptyScanner; }
- set => SetProperty(ref _isEmptyScanner, value);
- }
- //没有生成图片
- private bool isEmptyImg;
- public bool IsEmptyImg
- {
- get { return isEmptyImg; }
- set => SetProperty(ref isEmptyImg, value);
- }
- public string Title => "";
- //图片路径
- public string FilePath { get; private set; }
- private bool IsScanner = false;
- public event Action<IDialogResult> RequestClose;
- private TwainSession twain;
- public DelegateCommand CancelCommand { get; set; }
- public DelegateCommand CreateCommand { get; set; }
- public DelegateCommand<object> SelectedScannerCommand { get; set; }
- public CreateFromScannerDialogsViewModel()
- {
- CancelCommand = new DelegateCommand(cancel);
- CreateCommand = new DelegateCommand(createFile, CanExcuteCreateFile).ObservesProperty(() => Img);
- SelectedScannerCommand = new DelegateCommand<object>(SelectedScanner);
- SetupTwain();
- if (Scanners.Count > 0)
- IsEmptyScanner = false;
- else
- IsEmptyScanner = true;
- }
- //选择扫描仪
- private void SelectedScanner(object obj)
- {
- if(obj != null)
- {
- if (twain.State == 4)
- {
- twain.CurrentSource.Close();
- }
- Img = null;
- OpenSaveScanner();
- var result = obj as ScannerItem;
- if (result.DataSourceItem.Open() != ReturnCode.Success)
- MessageBox.Show("连接失败");
- else
- {
-
- }
- Preview();
- }
-
- }
- //启动检测扫描仪
- private void SetupTwain()
- {
- var appId = TWIdentity.CreateFromAssembly(DataGroups.Image, Assembly.GetEntryAssembly());
- twain = new TwainSession(appId);
- twain.Open();
- //Todo:在程序32位时,可正常扫描;
- //在程序64位时,不能正常获取扫描仪,并崩溃:找不到TWAINDSM.DLL模块。
- foreach (var s in twain.Select(s => new { DS = s }))
- {
- var item = new ScannerItem(s.DS);
- Scanners.Add(item);
- }
- twain.TransferError += (s, e) =>
- {
- CloseSaveScanner();
- // MessageBox.Show("图片传输错误:" + e.Exception.Message);
- };
- twain.DataTransferred += _session_DataTransferred;
- twain.SourceDisabled += (s, e) =>
- {
- //MessageBox.Show("源数据已清除");
- };
- twain.TransferReady += (s, e) =>
- {
- //MessageBox.Show("数据传输就绪");
- };
- twain.SynchronizationContext = System.Threading.SynchronizationContext.Current;
- }
- //生成图片+预览图片
- private void _session_DataTransferred(object sender, DataTransferredEventArgs e)
- {
- if (IsScanner)
- {
- string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
- FilePath = docPath + "\\" + DateTime.Now.ToString("yyyy-MM-dd_hh-mm-ss") + ".png";
- var encoder = new PngBitmapEncoder();
- encoder.Frames.Add(BitmapFrame.Create(e.GetNativeImageStream().ConvertToWpfBitmap(300, 0)));
- var test = encoder.Frames[0];
- FileStream fileStream = new FileStream(FilePath, FileMode.Create, FileAccess.ReadWrite);
- encoder.Save(fileStream);
- fileStream.Close();
- CloseSaveScanner();
- }
- ImageSource img = GenerateThumbnail(e);
- if (img != null)
- {
- App.Current.Dispatcher.BeginInvoke(new Action(() =>
- {
- Img = img;
- }));
- }
- }
- //图片缩略图
- private ImageSource GenerateThumbnail(DataTransferredEventArgs e)
- {
- BitmapSource img = null;
- switch (e.TransferType)
- {
- case XferMech.Native:
- using (var stream = e.GetNativeImageStream())
- {
- if (stream != null)
- {
- // twain.CurrentSource.Capabilities.ICapYResolution.SetValue();
- img = stream.ConvertToWpfBitmap(300, 0);
- }
- }
- break;
- case XferMech.File:
- img = new BitmapImage(new Uri(e.FileDataPath));
- if (img.CanFreeze)
- {
- img.Freeze();
- }
- break;
- case XferMech.Memory:
- // TODO: build current image from multiple data-xferred event
- break;
- }
- return img;
- }
- //预览图片
- private void Preview()
- {
- if (twain.CurrentSource == null) return;
- var windowsPtr = new WindowInteropHelper(Window.GetWindow(App.Current.MainWindow)).Handle;
- twain.CurrentSource.Enable(SourceEnableMode.NoUI, false, windowsPtr);
- }
- private void CloseSaveScanner()
- {
- IsScanner = false;
- }
- private void OpenSaveScanner()
- {
- IsScanner = true;
- }
- /// <summary>
- /// 是否可以创建
- /// </summary>
- /// <returns></returns>
- private bool CanExcuteCreateFile()
- {
- if (Img == null)
- IsEmptyImg = true;
- else
- IsEmptyImg = false;
- return (Img != null);
- }
- //扫描,创建文件
- private void createFile()
- {
- DialogParameters valuePairs = new DialogParameters();
- valuePairs.Add(ParameterNames.DataModel, FilePath);
- RequestClose.Invoke(new DialogResult(ButtonResult.OK, valuePairs));
- }
- private void cancel()
- {
- RequestClose.Invoke(new DialogResult(ButtonResult.Cancel));
- }
- #region 框架
- public bool CanCloseDialog()
- {
- return true;
- }
- public void OnDialogClosed()
- {
- }
- public void OnDialogOpened(IDialogParameters parameters)
- {
- }
- #endregion
- }
- }
|