UWP的掃描儀功能如今被微軟劃分到了[Windows Desktop Extensions for the UWP]中,若是要使用掃描儀掃描圖片到本身的App中,首先咱們要添加[Windows Desktop Extensions for the UWP]的引用,這個dll中的全部類都是隻能在Desktop設備上才能正常運行的。添加[Windows Desktop Extensions for the UWP]express
掃描儀須要用Windows.Devices.Scanners 命名空間下的成員,有幾個很重要的成員先介紹下:dom
ImageScanner 類async
- ImageScanner.DefaultScanSource //獲取爲此掃描儀設備選擇的默認掃描源
- ImageScanner.DeviceId //獲取此掃描儀設備的 PnP 設備標識符
- ImageScanner.FlatbedConfiguration //獲取並設置平板掃描單元的掃描設置,如掃描分辨率和顏色模式
- ImageScanner.FromIdAsync //建立基於掃描儀設備信息 ID 的 ImageScanner 對象的實例
- ImageScanner.ScanFilesToFolderAsync //掃描文件到文件夾 ,支持進度報告
- ImageScanner.ScanPreviewToStreamAsync //掃描文件到流
ImageScannerFlatbedConfiguration 類(這個類裏面有不少屬性都是和設置掃描儀有關的,主要的以下,其餘就不一一列舉了)ide
- ImageScannerFlatbedConfiguration.ColorMode //獲取或設置平板掃描儀的顏色模式如黑白灰度等
- ImageScannerFlatbedConfiguration.DesiredResolution //獲取或設置應用程序請求的掃描儀平板的水平和垂直掃描分辨率(以 DPI 爲單位)
- ImageScannerFlatbedConfiguration.Format //獲取或設置從掃描儀的平板到客戶端應用程序的圖像數據獲取的當前文件傳輸格式。
- ImageScannerFlatbedConfiguration.SelectedScanRegion //獲取或設置選定掃描區域的原始座標(水平和垂直)和維度(寬度和高度)(以英寸爲單位)
接下來,咱們須要一臺掃描儀,掃描儀裝好驅動,並支持WIA 2.0 .個人是TOSHIBA 2008S學習
而後建立一個頁面,前臺代碼以下:動畫
1 <Page.BottomAppBar> 2 <CommandBar> 3 <CommandBar.Content> 4 <Grid/> 5 </CommandBar.Content> 6 <AppBarButton Icon="Scan" Label="Scan Images" x:Name="Bar_ScanFiles" Click="Bar_ScanFiles_Click"/> 7 </CommandBar> 8 </Page.BottomAppBar> 9 10 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" > 11 <Viewbox> 12 <Grid> 13 <Path Data="M0,589.122C7.23756,591.35,15.1453,592.686,23.5452,592.686L734.433,592.686C742.831,592.686,750.74,591.35,758,589.122L746.228,633.25C746.228,642.477,735.684,650,722.639,650L35.3397,650C22.3137,650,11.7945,642.477,11.7945,633.25z M410.134,418.119L541.24,418.119 635.51,532.435 363.028,532.435z M209.217,402.719C198.74,402.719,195.772,408.064,187.462,416.255L73.5126,540.241C73.5126,547.715,81.9774,553.729,92.4548,553.729L378.964,553.729 665.473,553.729C675.95,553.729,684.484,547.715,684.484,540.241L570.516,416.255C562.228,408.064,559.258,402.719,548.757,402.719L378.964,402.719z M168.384,389.421L378.964,389.421 589.591,389.421C602.638,389.421,606.277,396.102,616.622,406.219L758,560.028C758,569.288,747.43,576.795,734.433,576.795L378.964,576.795 23.5452,576.795C10.5443,576.795,0,569.288,0,560.028L141.375,406.219C151.651,396.102,155.358,389.421,168.384,389.421z M164.949,0L378.966,0 593.029,0C606.078,-5E-06,616.621,7.50893,616.621,16.7822L616.621,358.018C616.621,367.277,606.078,374.785,593.029,374.785L378.966,374.785 164.949,374.785C151.925,374.785,141.379,367.277,141.379,358.018L141.379,16.7822C141.379,7.50893,151.925,-5E-06,164.949,0z" Stretch="Uniform" Fill="#FF434343" Width="160" Height="160" Margin="0,0,0,0" RenderTransformOrigin="0.5,0.5"> 14 <Path.RenderTransform> 15 <TransformGroup> 16 <TransformGroup.Children> 17 <RotateTransform Angle="0" /> 18 <ScaleTransform ScaleX="0.5" ScaleY="0.5" /> 19 </TransformGroup.Children> 20 </TransformGroup> 21 </Path.RenderTransform> 22 </Path> 23 </Grid> 24 </Viewbox> 25 26 <GridView x:Name="ImgList"></GridView> 27 28 </Grid>
後臺代碼以下:spa
1 /// <summary> 2 /// 開始掃描 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private async void Bar_ScanFiles_Click(object sender, RoutedEventArgs e) 7 { 8 var scanner = await GetScanner(); 9 if (scanner == null) return; 10 11 //保存至用戶圖片庫 12 //var results = await scanner.ScanFilesToFolderAsync(scanner.DefaultScanSource, KnownFolders.PicturesLibrary); 13 14 //取消任務的Token 15 cancellationToken = new CancellationTokenSource(); 16 17 //掃描中的對話框 18 ContentDialog dialog = new ContentDialog(); 19 dialog.Title = new TextBlock { Text = "掃描中...", FontSize = 14 }; 20 dialog.Content = new Scaning() { Width = 200, Height = 200 }; 21 dialog.PrimaryButtonText = "取消"; 22 dialog.PrimaryButtonClick += (s, a) => 23 { 24 cancellationToken.Cancel(); 25 cancellationToken.Token.Register(() => 26 { 27 dialog.Hide(); 28 }); 29 }; 30 dialog.ShowAsync(); 31 try 32 { 33 //獲取預覽 ->直接返回 Stream 不過圖片質量不好 34 //IRandomAccessStream stream = new InMemoryRandomAccessStream(); 35 //await scanner.ScanPreviewToStreamAsync(scanner.DefaultScanSource, stream).AsTask(cancellationToken.Token); 36 37 //掃描 -> 獲取到掃描完成的文件 38 var files = await Scanner.ScanFilesToFolderAsync(Scanner.DefaultScanSource, KnownFolders.SavedPictures).AsTask(cancellationToken.Token); 39 40 for (int i = 0; i < files.ScannedFiles.Count; i++) 41 { 42 //建立文件讀取流 43 using (var fileStream = await files.ScannedFiles[i].OpenStreamForReadAsync()) 44 { 45 var bitmap = new BitmapImage(); 46 await bitmap.SetSourceAsync(fileStream.AsRandomAccessStream()); 47 ImgList.Items.Add(new Image { Source = bitmap }); 48 } 49 //用完流後刪除下圖片 50 await Task.Factory.StartNew(() => File.Delete(files.ScannedFiles[i].Path)); 51 } 52 } 53 catch (TaskCanceledException) 54 { 55 Debug.WriteLine("A task was canceled."); 56 } 57 catch (Exception) 58 { 59 Debug.WriteLine("掃描出錯"); 60 } 61 finally 62 { 63 dialog.Hide(); 64 } 65 } 66 67 /// <summary> 68 /// 獲取掃描儀對象 69 /// </summary> 70 /// <returns>ImageScanner</returns> 71 private async Task<ImageScanner> GetScanner() 72 { 73 try 74 { 75 var device = await DeviceInformation.FindAllAsync(DeviceClass.ImageScanner); 76 var scanner = await ImageScanner.FromIdAsync(device.FirstOrDefault().Id); 77 return scanner; 78 } 79 catch (Exception) 80 { 81 await OpenScannerWithError("你能夠嘗試如下操做後重試:\r\n一、未發現可用的掃描儀設備\r\n二、沒有安裝適合的WIA2.0兼容驅動程序", 82 true, "重試", true, "取消", 83 () => { Bar_ScanFiles_Click(null, null); }); 84 return null; 85 } 86 } 87 88 /// <summary> 89 /// 彈出錯誤提示 90 /// </summary> 91 /// <param name="error">錯誤描述</param> 92 /// <param name="hasPrimaryBtn">是否具備主按鈕</param> 93 /// <param name="primaryBtnText">主按鈕Text</param> 94 /// <param name="hasSecondaryBtn">是否具備副按鈕</param> 95 /// <param name="secondaryBtnText">副按鈕Text</param> 96 /// <param name="primaryBtnClick">主按鈕點擊後執行的方法</param> 97 /// <param name="secondaryBtnClick">副按鈕點擊後執行的方法</param> 98 /// <returns>null</returns> 99 private async Task OpenScannerWithError(string error, bool hasPrimaryBtn = false, string primaryBtnText = null, bool hasSecondaryBtn = false, string secondaryBtnText = null, Action primaryBtnClick = null, Action secondaryBtnClick = null) 100 { 101 ContentDialog dialog = new ContentDialog(); 102 var dialogTitle = new StackPanel(); 103 104 dialogTitle.Children.Add(new TextBlock { Text = "出錯啦 ( ▼-▼ )", Foreground = new SolidColorBrush(Colors.Red) }); 105 106 var dialogContent = new StackPanel() { Margin = new Thickness(0, 12, 0, 0) }; 107 108 dialogContent.Children.Add(new TextBlock { Text = error }); 109 110 dialog.Title = dialogTitle; 111 112 dialog.Content = dialogContent; 113 114 if (hasPrimaryBtn) 115 { 116 dialog.PrimaryButtonText = "重試"; 117 if (primaryBtnClick != null) 118 { 119 dialog.Hide(); 120 dialog.PrimaryButtonClick += (s, a) => 121 { 122 primaryBtnClick(); 123 }; 124 } 125 } 126 127 if (hasSecondaryBtn) 128 { 129 dialog.SecondaryButtonText = "取消"; 130 131 dialog.SecondaryButtonClick += (s, a) => 132 { 133 dialog.Hide(); 134 if (secondaryBtnClick != null) 135 { 136 secondaryBtnClick(); 137 } 138 }; 139 } 140 await dialog.ShowAsync(); 141 }
用到的一個UserControl –> Scaning, 是用來顯示掃描中動畫的,前臺代碼以下:3d
1 <UserControl 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:local="using:ScannerDeviceSample.UserControls" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 7 xmlns:Interactivity="using:Microsoft.Xaml.Interactivity" xmlns:Core="using:Microsoft.Xaml.Interactions.Core" xmlns:Media="using:Microsoft.Xaml.Interactions.Media" 8 x:Class="ScannerDeviceSample.UserControls.Scaning" 9 mc:Ignorable="d" 10 d:DesignHeight="200" 11 d:DesignWidth="200"> 12 <UserControl.Resources> 13 <Storyboard x:Name="ScaningStoryboard" AutoReverse="True" RepeatBehavior="Forever"> 14 <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="recScanning"> 15 <EasingDoubleKeyFrame KeyTime="0" Value="0"/> 16 <EasingDoubleKeyFrame KeyTime="0:0:2" Value="-200"/> 17 </DoubleAnimationUsingKeyFrames> 18 </Storyboard> 19 </UserControl.Resources> 20 21 <Interactivity:Interaction.Behaviors> 22 <Core:EventTriggerBehavior EventName="Loaded"> 23 <Media:ControlStoryboardAction Storyboard="{StaticResource ScaningStoryboard}"/> 24 </Core:EventTriggerBehavior> 25 </Interactivity:Interaction.Behaviors> 26 27 <Grid> 28 <Path Data="M2.8160041,17.083004L2.8160041,18.351004 15.944004,18.351004 15.944004,17.083004z M2.8160041,13.907004L2.8160041,15.174004 15.944004,15.174004 15.944004,13.907004z M2.8160041,10.731004L2.8160041,11.999004 15.944004,11.999004 15.944004,10.731004z M0,1.356853E-05L10.572985,1.356853E-05 10.572985,7.9669956 18.761999,7.9669956 18.761999,21.176014 0,21.176014z M11.945004,0L18.761988,6.6610196 11.945004,6.6610196z" Stretch="Uniform" Fill="Black" Width="128" Height="128" Margin="0,0,0,0" RenderTransformOrigin="0.5,0.5"> 29 <Path.RenderTransform> 30 <TransformGroup> 31 <RotateTransform Angle="0" /> 32 <ScaleTransform ScaleX="0.8" ScaleY="1" /> 33 </TransformGroup> 34 </Path.RenderTransform> 35 </Path> 36 <Rectangle x:Name="recScanning" Height="2" RenderTransformOrigin="0.5,0.5" VerticalAlignment="Bottom" d:LayoutOverrides="Height"> 37 <Rectangle.RenderTransform> 38 <CompositeTransform/> 39 </Rectangle.RenderTransform> 40 <Rectangle.Projection> 41 <PlaneProjection/> 42 </Rectangle.Projection> 43 <Rectangle.Fill> 44 <LinearGradientBrush EndPoint="0,0.5" StartPoint="1,0.5"> 45 <GradientStop Color="#331CF106" Offset="0.15"/> 46 <GradientStop Color="#331CF106" Offset="0.85"/> 47 <GradientStop Color="#FF1CF106" Offset="0.5"/> 48 </LinearGradientBrush> 49 </Rectangle.Fill> 50 </Rectangle> 51 </Grid> 52 </UserControl>
最後的效果:code
推薦一個UWP開發羣:53078485 你們能夠進來一塊兒學習~~orm