WINDOWS 10 2015 年特別版
此文章由機器翻譯。
# 數字墨跡 - Windows 10 中的墨跡交互
通過?[Connor Weins](https://msdn.microsoft.com/zh-cn/magazine/mt149362?author=Connor+Weins)?|Windows 2015 年
在本文中,我將介紹如何將提升自然的用戶交互使用墨跡書寫。數字墨跡,很像在紙上、 筆從您的數字筆設備、 筆針、 手指或鼠標的提示將排并呈現在屏幕上。若要獲取開始與數字墨跡和手寫 Windows 10 中,我將首先通過解決基本問題: 為什么是您必須在您的應用程序中使用墨跡?
人類具有已傳達的想法和創意通過手寫世紀。盡管鼠標和鍵盤的發明,筆和紙方法仍扮演著關鍵角色在我們的生活中 — 從粘滯便箋的步驟和我們的辦公室中我們學校筆記本和我們的孩子他人之手著色叢書中的白板。
筆和紙是即時、 自由格式且唯一個人到我們每一個人,這使得用戶可利用來表示他們的創造力和情感的理想選擇。將想法轉換成文本和到筆記的關系圖的 act 還會使手寫更適合進行思考、 記憶和學習,根據 2013年研究發布到心理科學中 ([bit.ly/1tKDrhv](http://bit.ly/1tKDrhv))、 從普林斯頓和 UCLA 研究人員在其中找到手寫的便箋已明顯優于類型化的說明為長期的理解。
與傳統的類型化的鍵盤輸入的墨跡這些優點,設想一下是否您可能會使手寫筆和紙和工具一樣容易的設備上的計算機的處理能力來執行現實生活中您不能執行的操作。使用數字墨跡,您可以輕松地改變顏色和墨跡的外觀就像在現實生活中,而采用其基礎上更進一步、 分析的內容和形狀的手寫內容來提供元數據,或將墨跡轉換為其他內容,如文本、 圖形或命令。它提供了您的日常 notebook,使數字墨跡繪圖、 筆記記錄批注以及在您的應用程序進行交互的功能強大的工具不能復制到的墨跡書寫的全新維度。隨著支持筆和觸摸的設備市場不斷擴大,墨跡書寫將成為用戶和應用程序開發人員交互的一個關鍵方法。
在 Windows 10 中,是便于您能夠將您的應用程序通過 DirectInk 平臺到數字墨跡書寫。DirectInk 提供了一套豐富且可擴展 Windows 運行時 (WinRT) 允許您收集、 呈現和管理在通用 Windows 平臺應用程序中的墨跡的 Api。通過使用 DirectInk,您可以獲得的同一個很好的手寫內容和 Microsoft 邊緣瀏覽器,通用 OneNote 和手寫板使用的性能。下面是 DirectInk 提供您的應用程序的功能的快速概述:
* 既美觀又具備手寫內容: DirectInk 使用輸入平滑處理并貝塞爾呈現算法以確保您的手寫內容始終看起來清晰和漂亮的觸摸和筆輸入。
* 低延遲、 內存不足: DirectInk 使用高優先級后臺線程和輸入的預測以確保手寫內容始終是即時且對用戶的響應能力和它所管理資源,有效地以保持您的應用程序開銷較低。
* 簡單而又可擴展的 API 圖面: DirectInk 提供了 Api (如 InkCanvas 和 InkPresenter,允許您快速地開始收集和管理墨跡,并提供允許您構建您的應用程序中的豐富而復雜的功能的高級的功能。
希望目前為止您非常高興地開始在您的應用程序中使用數字墨跡。現在將一看如何在您的應用程序中利用 DirectInk 平臺并為用戶提供更完美的墨跡書寫體驗。
## 收集應用程序中的墨跡
若要開始使用數字墨跡,第一步是設置了一個可以收集和呈現為墨跡輸入面。在 Windows 8.1 應用商店應用程序中引入到您的應用程序的墨跡書寫時涉及到創建一個畫布,偵聽事件,以及如何創建和呈現筆畫--逐一使用您自己的呈現代碼輸入一個擴展的過程。對于通用 Windows 應用程序,以收集手寫內容的開頭是像將 InkCanvas 放到您的應用程序一樣簡單:
~~~
<Grid>
? <InkCanvas x:Name="myInkCanvas"/>
</Grid>
~~~
如您所見中?圖 1, ,這行代碼為您提供開始收集的筆輸入和輸入為黑色圓珠筆的呈現的透明覆蓋。將筆橡皮擦按鈕還將擦除它自帶聯系任何收集的手寫內容。盡管這是很好的入門知識的墨跡書寫,如果想要更改墨跡收集或顯示如何?

圖 1 使用 InkCanvas 以收集手寫內容類似于黑色圓珠筆
通過 InkCanvas,您可以訪問您的 InkPresenter,公開用于控制外觀和墨跡的輸入的配置的功能。雖然筆輸入提供了最佳的用戶體驗的墨跡書寫,許多系統不會配備用筆。只需將會收集筆、 觸摸和鼠標輸入和您沒有選擇的輸入的類型的任意組合的墨跡 InkPresenter 允許傳遞作為到 InkCanvas XAML 元素的指針事件。通過 InkPresenter,還可以管理繪圖的墨水在 InkCanvas,從而允許您更改畫筆大小、 顏色及更多內容上收集的屬性的默認值。這些功能的示例,作為您的應用程序可以將配置您 InkCanvas 以收集手寫筆、 觸摸和鼠標輸入,并通過執行以下操作模擬書法畫筆:
~~~
InkPresenter myPresenter = myInkCanvas.InkPresenter;
myPresenter.InputDeviceTypes = Windows.UI.Core.CoreInputDeviceTypes.Pen |
?????????????????????????????? Windows.UI.Core.CoreInputDeviceTypes.Touch |
?????????????????????????????? Windows.UI.Core.CoreInputDeviceTypes.Mouse;
InkDrawingAttributes myAttributes = myPresenter.CopyDefaultDrawingAttributes();
myAttributes.Color = Windows.UI.Colors.Crimson;
myAttributes.PenTip = PenTipShape.Rectangle;
myAttributes.PenTipTransform =
? System.Numerics.Matrix3x2.CreateRotation((float) Math.PI/4);
myAttributes.Size = new Size(2,6);
myPresenter.UpdateDefaultDrawingAttributes(myAttributes);
~~~
程序將生成結果中所示?圖 2。

圖 2 模擬書法畫筆使用 InkPresenter DrawingAttributes
DirectInk 支持許多內置了更多配置輸入和手寫內容呈現允許您呈現作為熒光筆墨跡、 接收事件收集筆畫時、 訪問細粒度的輸入的事件和墨跡具有高級配置中的多個指針。
## 編輯、 保存和加載墨跡
因此既然您已經收集一些墨跡,什么您如何使用它? 用戶經常需要擦除或編輯的墨跡收集它們,或保存以后訪問該手寫內容的能力。為了給您的用戶提供這種體驗,您必須以訪問和修改 DirectInk 已呈現在屏幕的筆畫的墨跡數據。
在您 InkCanvas 上不會收集手寫內容,DirectInk 內 InkPresenter InkStrokeCollection 內存儲它。此 InkStrokeCollection 包含 WinRT 對象來表示每個當前在您畫布上的筆畫和更改對此容器進行了您的應用程序,它們將還將呈現在屏幕上。這允許您以編程方式添加、 刪除或修改筆畫,并允許 DirectInk 可幫助您了解到在屏幕上的筆畫它做的任何更改。讓我們看看一些常見的用戶交互可以實現使用 InkPresenter 和其 InkStrokeContainer 之間的連接。
Erasing?雖然 InkCanvas 支持擦除使用筆橡皮擦按鈕默認情況下,但它需要在 InkPresenter 清除墨跡的鼠標和觸摸輸入一些配置。DirectInk 提供內置支持擦除通過 InputProcessingConfiguration 中的模式屬性的任何受支持的輸入的墨跡。下面是舉例說明如何將 Erasing 模式設置為一個按鈕:
~~~
private void Eraser_Click(object sender,
? RoutedEventArgs e)
{
? myInkCanvas.InkPresenter.
??? InputProcessingConfiguration.Mode =
??? InkInputProcessingMode.Erasing;
}
~~~
按下此按鈕時,DirectInk 收集 InkCanvas 的所有輸入將被都視為橡皮擦。如果設置此模式后,用戶輸入與筆畫相交,則將從 InkPresenter InkStrokeContainer 中刪除該筆劃,并將其從屏幕上刪除。當使用筆墨跡書寫模式下的,橡皮擦按鈕將始終被視為擦除模式。
選擇?遺憾的是,DirectInk 不具有對這一次,在內置的選定內容的支持,但它確實提供了一種方法來通過未處理的輸入事件自己開發。只要 DirectInk 收到告訴偵聽,但不是能呈現到墨跡輸入引發未處理的事件。這可以通過設置處理配置模式下為無 DirectInk 完成對所有輸入并還可以配置為發生這種情況僅用于鼠標右按鈕和筆筆桿按鈕使用 RightDragAction 屬性:
~~~
myInkCanvas.InkPresenter.InputProcessingConfiguration.RightDragAction =
? InkInputRightDragAction.LeaveUnprocessed;
~~~
例如,?圖 3?顯示了如何使用未處理的輸入事件以使所選內容套索 (如中所示?圖 4)?選擇在屏幕上的筆畫。
圖 3 使用未處理的輸入的事件以使所選內容套索
~~~
...
myInkCanvas.InkPresenter.UnprocessedInput.PointerPressed += StartLasso;
myInkCanvas.InkPresenter.UnprocessedInput.PointerMoved += ContinueLasso;
myInkCanvas.InkPresenter.UnprocessedInput.PointerReleased += CompleteLasso;
...
private void StartLasso(
? InkUnprocessedInput sender,Windows.UI.Core.PointerEventArgs args)
{
? selectionLasso = new Polyline()
? {
??? Stroke = new SolidColorBrush(Windows.UI.Colors.Black),
??? StrokeThickness = 2,
??? StrokeDashArray = new DoubleCollection() { 7, 3},
? };
? selectionLasso.Points.Add(args.CurrentPoint.RawPosition);
? AddSelectionLassoToVisualTree();
}
private void ContinueLasso(
? InkUnprocessedInput sender, Windows.UI.Core.PointerEventArgs args)
{
? selectionLasso.Points.Add(args.CurrentPoint.RawPosition);
}
private void CompleteLasso(
? InkUnprocessedInput sender, Windows.UI.Core.PointerEventArgs args)
{
? selectionLasso.Points.Add(args.CurrentPoint.RawPosition);
? bounds =
??? myInkCanvas.InkPresenter.StrokeContainer.SelectWithPolyLine(
??? selectionLasso.Points);
? DrawBoundingRect(bounds);
}
~~~

圖 4 選擇使用套索筆畫
您選擇的筆畫后,可以使用 InkStrokeContainer.MoveSelected 方法來轉換筆畫,或使用 InkStroke.PointTransform 屬性將仿射轉換應用于這些筆畫。以這種方式轉換描邊或筆畫 InkStrokeContainer 由管理組時, DirectInk 將拾取這些更改并呈現到屏幕。
保存和加載?DirectInk 本身支持手寫內容保存并加載通過墨跡序列化格式 (ISF),它將手寫內容保存在矢量格式使其成為共享和編輯、 更簡單。這是通過 InkStrokeContainer SaveAsync 和 LoadAsync 函數可訪問。
SaveAsync 采用當前存儲在 InkStrokeContainer 的筆畫數據并將其保存為 GIF 文件與嵌入 ISF 數據。圖 5?演示如何將手寫內容保存從您 InkStrokeContainer。
圖 5 將手寫內容保存從 InkStrokeContainer
~~~
var savePicker = new FileSavePicker();
savePicker.SuggestedStartLocation =
? Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
savePicker.FileTypeChoices.Add("Gif with embedded ISF",
? new System.Collections.Generic.List<string> { ".gif" });
StorageFile file = await savePicker.PickSaveFileAsync();
if (null != file)
{
? try
? {
??? using (IRandomAccessStream stream =
????? await file.OpenAsync(FileAccessMode.ReadWrite))
??? {
????? await myInkCanvas.InkPresenter.StrokeContainer.SaveAsync(stream);
??? }?
? }
? catch (Exception ex)
? {
??? GenerateErrorMessage();
? }
}
~~~
LoadAsync 將執行相反的函數中,清除已在您 InkStrokeContainer 筆畫,并從 ISF 文件或 GIF 文件與嵌入 ISF 數據加載一組新的筆畫。筆畫載入 InkStrokeContainer 后,DirectInk 自動將呈現它們在屏幕上。
## 高級墨跡書寫功能
開發帶有手寫內容的用戶交互的關鍵能夠編輯和處理在屏幕上的手寫內容時,它可能不是不足以滿足您的需要。更多創意希望您的應用程序以支持交互,您的應用程序將具有以中斷的交互 DirectInk 提供了一組默認的越多。讓我們深入了解 DirectInk 使您能夠構建豐富而獨特的手寫功能的方式的少數幾個:
墨跡書寫識別?墨跡是不止是在屏幕上的像素。用戶的墨跡可以解釋為圖片、 關系圖、 形狀或文本。識別用戶的墨跡的內容,可將手寫內容相關聯以致其意義或交換與它所代表的內容的墨跡。例如,如果用戶在筆記記錄應用程序中編寫文本,您的應用程序可以識別手寫內容表示,用于當用戶搜索欄中輸入一個查詢時生成搜索結果中使用該文本數據的文本。InkRecognizerContainer 供電意識到這種方式中的文本。圖 6?演示如何使用 InkRecognizerContainer 以將手寫內容解釋為簡體中文字符。
圖 6 使用 InkRecognizerContainer 簡體中文字符作為解釋筆跡
~~~
async void OnRecognizeAsync(object sender, RoutedEventArgs e)
{
? InkRecognizerContainer recoContainer = new InkRecognizerContainer();
? IReadOnlyList<InkRecognizer> installedRecognizers =
??? recoContainer.GetRecognizers();
? foreach (InkRecognizer recognizer in installedRecognizers)
? {
??? if (recognizer.Name.Equals("Microsoft 中文(簡體)手寫識別器"))
??? {
????? recoContainer.SetDefaultRecognizer(recognizer);
????? break;
??? }
? }
? var results = await recoContainer.RecognizeAsync(
??? myInkCanvas.InkPresenter.StrokeContainer,InkRecognitionTarget.All);
? if (results.Count > 0)
? {
??? string str = "Result:";
??? foreach (var r in results)
??? {
????? str += " " + r.GetTextCandidates()[0];
??? }
? }
}
~~~
而這將允許你將手寫內容識別為文本,InkRecognizerContainer 在于它當前支持從僅 33 不同的語言包的識別文本有限制。如果您想要識別從另一種語言的文本或識別符號、 圖形或其他更抽象的墨跡解釋,您需要構建該邏輯從零開始。幸運的是,該 InkStroke 對象所提供 GetInkPoints 函數,使你能獲取 x / y 位置的每個輸入點用于構造與筆畫。據此,您可以構建一種算法來分析筆劃的輸入的點或一組筆劃并隨意對其進行解釋 — 為符號,形狀、 命令或您的想象力的任何能想到的 !
獨立輸入?DirectInk 是一種功能強大的引擎為在一組簡單的輸入的規則下運行的呈現墨跡 — 呈現一個給定的筆劃的墨跡或不。若要使此決定,它看起來在受支持的輸入的類型的輸入處理模式提供配置和右拖放操作配置。這缺少了大量您的應用程序可能想要提供的墨跡書寫的上下文 — 您的應用程序可能不允許在畫布上的某些部分中的墨跡書寫或可能有手勢的墨跡書寫應在停止后識別出的筆勢。若要啟用您做出這樣的決策,DirectInk 提供輸入之前它將開始處理通過獨立輸入事件的訪問權限。這些事件使您能夠之前 DirectInk 因此如果不允許的墨跡書寫區域或完成手勢移動事件中收到一個按下的事件您期盼已久的只是可以將標記該事件作為 Handled 已呈現它,檢查輸入。
DirectInk 時該事件被標記為 Handled,將停止處理筆畫,并且如果一個筆劃已過程中,它將取消并從屏幕上刪除。您需要時使用這些事件,但請務必小心。它們而不是 UI 線程的 DirectInk 后臺線程上發生了,因為任何處理工作繁重您在執行操作的事件或等待如 UI 線程可能會引入會影響您的手寫內容的響應能力的滯后時間在速度較慢的線程中運行的活動。
自定義干?DirectInk 最復雜的功能之一是烘干自定義的模式,它允許您的應用程序來呈現和管理已完成或"干"墨跡筆畫時讓 DirectInk 處理正在進行的高性能呈現、 您自己 DirectX 表面上或"濕"墨跡筆畫。雖然 DirectInk 的默認烘干模式可以處理大多數情況下可能需要在您的應用程序中啟用,但是了幾種方案需要您可以獨立地管理墨跡:
* 在保持 z 順序的同時交替墨跡和非手寫內容 (文本、 形狀)
* 高性能平移和縮放到大型墨跡畫布上具有大量墨跡筆畫
* 轉換為直線或形狀類似的 DirectX 對象以同步方式烘干墨跡
在 Windows 10 自定義烘干模式支持與 SurfaceImageSource (SIS) 或 VirtualSurfaceImageSource (VSI) 同步。SIS 和 VSI 提供您的應用程序繪制到和撰寫,DirectX 共享圖面雖然 VSI 提供了虛擬的表面大于平移和縮放的高性能的屏幕。當手寫內容呈現到 SIS 或 VSI,視覺對象更新到這些表面會同步到 XAML UI 線程上,因為它可以刪除從 DirectInk 濕層同時。自定義 Drying 也支持烘干墨跡轉換為 SwapChainPanel 但并不能保證同步。因為 SwapChainPanel 不與 UI 線程同步的則將有之間小重疊時手寫內容呈現給您 SwapChainPanel 而當從 DirectInk 濕手寫內容圖層中刪除手寫內容。
時您激活烘干自定義時,你會獲得的許多功能都 DirectInk 提供默認情況下,允許您以構建呈現和從您干的圖面中刪除手寫內容的方式的邏輯并確定如何將墨跡筆劃數據管理您的應用程序的精細控制。為了幫助您生成此項功能,許多 DirectInk 組件都可用作獨立對象以填充空白幫助您的應用程序。自定義烘干激活時,DirectInk 提供了一個 InkSynchronizer 對象,它允許您開始和結束烘干過程以便墨跡刪除從 DirectInk 濕層與同步時將其添加到您的自定義干層。DirectInk 默認干墨呈現邏輯它也可通過 InkD2DRender 以確保墨跡外觀濕和干層之間保持一致。有關擦除,可以使用未處理的輸入事件生成擦除邏輯類似于前面的示例。
有關詳細信息和使用自定義烘干的示例,請查看 ComplexInk 示例可在 GitHub 上?[bit.ly/1NkRjt7](http://bit.ly/1NkRjt7)。
## 開始創建具有墨跡
使用您已了解到目前為止有關 InkCanvas、 InkPresenter 和 InkStrokeContainer 中,您現在可以收集手寫內容的不同類型的輸入,自定義如何顯示的墨跡在屏幕上訪問筆畫數據并具有對筆畫數據的更改會反映在由 DirectInk 呈現墨跡筆劃。與該簡單級別的功能,您可以構建范圍廣泛的用戶交互,從簡單靈機一動詳細專注于方案的功能,例如筆記記錄和收集用戶的簽名。您還可以用于構建更復雜的交互通過 InkRecognizerContainer,獨立的輸入事件和自定義烘干模式下的工具。
使用可供您使用這些工具,您的應用程序應該能夠利用所有數字墨跡可以提供給您的用戶提供更完美的墨跡書寫體驗的優勢。隨著的筆和觸控啟用的設備數量不斷增加,為客戶提供更完美的墨跡書寫體驗將變得更為重要的用戶的滿意度和應用程序的區分作用。希望您可能需要一些時間想有關數字墨跡書寫程序可以在您的應用程序中工作并開始試驗 DirectInk。
最后請注意,墨跡書寫仍然是 microsoft 的投資的重要區域以及對改進的最大密鑰之一并展開針對將來版本的 DirectInk 平臺是我們的開發人員社區的反饋。如果在使用 DirectInk 進行開發時有任何疑問、 意見或想法,請將它們發送到?[DirectInk@microsoft.com](mailto:DirectInk@microsoft.com)。
* * *
Connor Weins?*是處理筆觸筆和墨跡書寫 Windows 開發人員生態系統平臺組中的團隊的項目經理。與他聯系?[conwei@microsoft.com](mailto:conwei@microsoft.com)。*
- 介紹
- Microsoft .NET - .NET 和通用 Windows 平臺開發
- 圖形和動畫 - Windows 組合支持 10 倍縮放
- 應用生命周期 - 通過后臺任務和擴展執行使應用處于活動狀態
- 通知 - Windows 10 中的自適應和交互式通知
- 應用集成 - 在 Windows 10 上鏈接和集成應用
- Visual Studio 工具 - NuGet 功能增強了 Windows 10 的開發功能
- UI 設計 - 通用 Windows 應用的響應式設計
- UI 設計 - 適用于 Windows 10 的自適應應用
- 數字墨跡 - Windows 10 中的墨跡交互
- 游戲開發 - 使用 Unity 為通用 Windows 平臺編寫游戲
- 結束語 - 歡迎使用 Windows 10 應用開發
- 編者寄語 - 從 3.0 開始的發展之路