Win10/UWP開發-Ink墨跡書寫


    在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 大家可以進來一起學習


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM