在UWP開發中,微軟提供了一個新型的InkCanvas控件用來讓用戶能書寫墨跡,在新版的Edga瀏覽器中微軟自己也用到了該控件使用戶很方便的可以在web上做筆記。
InkCanvas控件使用很簡單,從工具箱里拖出一個InkCanvas控件即可,InkCanvas有個屬性叫InkPresenter,通過它我們可以多樣化的設置我們的畫筆屬性,InkPresenter里面有幾個重要的屬性:
1 // 獲取或設置輸入數據用於從中提取 InkStroke 的輸入設備類型。 2 3 public CoreInputDeviceTypes InputDeviceTypes { get; set; } 4 5 6 // 獲取 InkCanvas 控件上的 InkStroke 的行為。例如,墨跡、清除或選擇。 7 8 public InkInputProcessingConfiguration InputProcessingConfiguration { get; } 9 10 11 // 獲取或設置是否已啟用輸入以進行墨跡書寫。 12 13 public System.Boolean IsInputEnabled { get; set; } 14 15 16 // 獲取或設置 InkStrokeContainer 對象以管理 InkCanvas 控件上的一個或多個 InkStroke 對象的輸入、處理和操作。 17 18 public InkStrokeContainer StrokeContainer { get; set; } 19 20 21 // 從關聯的 InkCanvas 控件獲取筆划墨跡輸入。 22 23 public InkStrokeInput StrokeInput { get; } 24 25 26 // 設置 InkCanvas 控件上一個或多個接觸點的墨跡書寫行為。 27 28 public void SetPredefinedConfiguration(InkPresenterPredefinedConfiguration value); 29 30 31 // 指定渲染新的 InkStroke 時 InkCanvas 控件所使用的 InkDrawingAttributes。 32 33 public void UpdateDefaultDrawingAttributes(InkDrawingAttributes value);
接下來我們做一個畫圖板,功能要實現墨跡書寫,墨跡擦除,墨跡保存,墨跡加載,手寫識別。
墨跡書寫
前台聲明一個InkCanvas控件:
<InkCanvas x:Name="InkCanvas" />
后台設置下Ink的墨筆屬性:
1 private void MainPage_Loaded(object sender, RoutedEventArgs e) 2 { 3 //設置輸入類型為觸控輸入和鼠標輸入 4 InkCanvas.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Touch; 5 //創建一個新的畫筆屬性(此步可省略,省略后采用默認畫筆) 6 var attr = new InkDrawingAttributes 7 { 8 Color = Colors.Red, //顏色 9 IgnorePressure = true, //是否忽略數字化器表面上的接觸壓力 10 PenTip = PenTipShape.Rectangle, //筆尖類型設置 11 Size = new Size(4, 10), //畫筆粗細 12 PenTipTransform = Matrix3x2.CreateRotation((float)(70 * Math.PI / 180)) //筆尖形狀矩陣 13 }; 14 //更新畫筆 15 InkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(attr); 16 }
墨跡擦除
墨跡擦除只需要設置畫筆行為為橡皮擦即可
InkCanvas.InkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.Erasing;
墨跡保存
1 private async void Btn_Save_OnClick(object sender, RoutedEventArgs e) 2 { 3 //聲明一個流來存儲墨跡信息 4 IRandomAccessStream stream = new InMemoryRandomAccessStream(); 5 //保存墨跡信息到流 6 //拿到流了就可以隨意處置墨跡了,可以保持到App內部 也可以保存為文件,我們直接保存為文件 7 await InkCanvas.InkPresenter.StrokeContainer.SaveAsync(stream); 8 //創建一個文件保存對話框 9 var picker = new Windows.Storage.Pickers.FileSavePicker 10 { 11 SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary 12 }; 13 //文件類型 14 picker.FileTypeChoices.Add("INK files", new List<string>() { ".ink" }); 15 //彈出保存對話框 16 var file = await picker.PickSaveFileAsync(); 17 if (file == null) return; 18 19 CachedFileManager.DeferUpdates(file); 20 //將流轉為byte 21 var bt = await ConvertImagetoByte(stream); 22 //寫入文件 23 await Windows.Storage.FileIO.WriteBytesAsync(file, bt); 24 //保存 25 await CachedFileManager.CompleteUpdatesAsync(file); 26 } 27 private async Task<byte[]> ConvertImagetoByte(IRandomAccessStream fileStream) 28 { 29 //IRandomAccessStream fileStream = await image.OpenAsync(FileAccessMode.Read); 30 var reader = new Windows.Storage.Streams.DataReader(fileStream.GetInputStreamAt(0)); 31 await reader.LoadAsync((uint)fileStream.Size); 32 33 byte[] pixels = new byte[fileStream.Size]; 34 35 reader.ReadBytes(pixels); 36 37 return pixels; 38 }
墨跡加載
1 private async void Btn_load_OnClick(object sender, RoutedEventArgs e) 2 { 3 //創建一個文件選擇器 4 var picker = new Windows.Storage.Pickers.FileOpenPicker 5 { 6 SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary 7 }; 8 //規定文件類型 9 picker.FileTypeFilter.Add(".ink"); 10 //顯示選擇器 11 var pickedFile = await picker.PickSingleFileAsync(); 12 if (pickedFile != null) 13 { 14 var file = await pickedFile.OpenReadAsync(); 15 //加載墨跡 16 await InkCanvas.InkPresenter.StrokeContainer.LoadAsync(file); 17 } 18 }
手寫識別
手寫識別是指通過用戶使用畫筆寫出的墨跡,我們可以識別出是什么內容,主要是通過InkRecognizerContainer類來完成的。
InkRecognizerContainer類有幾個主要方法:
// 獲取 InkRecognizer 對象的集合。 public IReadOnlyList<InkRecognizer> GetRecognizers(); // 對一個或多 InkStroke 對象執行手寫識別。 public IAsyncOperation<IReadOnlyList<InkRecognitionResult>> RecognizeAsync(InkStrokeContainer strokeCollection, InkRecognitionTarget recognitionTarget); // 設置用於手寫標識的默認 InkRecognizer。 public void SetDefaultRecognizer(InkRecognizer recognizer);
具體使用方法:
1 private async void btnOcr_OnClick(object sender, RoutedEventArgs e) 2 { 3 //手寫識別 4 var container = new InkRecognizerContainer(); 5 //使用墨跡識別 6 var result = await container.RecognizeAsync(InkCanvas.InkPresenter.StrokeContainer, InkRecognitionTarget.All); 7 //獲取識別結果 InkRecognitionResult 對象中還能獲取候選字 8 var txt = result[0].GetTextCandidates()[0]; 9 10 var dia = new ContentDialog() 11 { 12 Content = new TextBlock() { Text = txt }, 13 PrimaryButtonText = "ok", 14 IsPrimaryButtonEnabled = true 15 16 }; 17 dia.PrimaryButtonClick += (s, a) => 18 { 19 dia.Hide(); 20 }; 21 await dia.ShowAsync(); 22 }
Ink Toolbar control
上面介紹了Ink控件的基本使用方法,其中最主要的就是畫筆屬性的設置,為了方便大家的開發,微軟還提供了一個輔助Control叫做Ink Toolbar,通過它,我們可以很方便的集成一個畫筆設置工具欄。
首先安裝該工具擴展,然后引用InkToolbar Control.dll,接着在View中聲明控件:
xmlns:ink="using:Microsoft.Labs.InkToolbarControl" <ink:InkToolbar x:Name="bar_InkTool" TargetInkCanvas="{x:Bind InkCanvas}" VerticalAlignment="Top" HorizontalAlignment="Right" />
TargetInkCanvas屬性bind到要設置的InkCanvas上即可。
效果圖:
推薦一個UWP開發群:53078485 大家可以進來一起學習