共用方式為



Windows 10 特刊 2015

第 30 卷,第 11 期

本文章是由機器翻譯。

數位筆跡 - Windows 10 中的筆跡整合

Connor Weins |Windows 2015

在本文中,我將討論您可以升級自然的使用者互動的方式使用手寫筆跡功能。數位筆墨,如同在紙張上的畫筆順著數位筆裝置、 手寫筆、 手指或滑鼠的秘訣和螢幕上呈現。若要取得啟動以數位筆墨和筆跡 Windows 10 中,我會先解決基本問題: 它為何如此重要供您使用應用程式中的筆墨?

人類有的想法和建議透過手寫已傳達數個世紀。滑鼠和鍵盤的發明,儘管畫筆及紙張方法仍然扮演重要的角色在我們的生活 — 從自黏便箋和我們辦公室、 在我們的學校筆記型電腦和我們的子系手中著色線上叢書 》 中的白板。

畫筆紙張的立即、 手繪多邊形和唯一個人到每一個人,讓其他人使用以表示他們的創意和情緒理想。將想法轉換成文字和備忘稿到圖表的動作也讓手寫更好的想法、 記住和學習、 根據 2013年研究發行在心理科學 (bit.ly/1tKDrhv)、 從 Princeton 和 UCLA 的研究人員找到手寫的筆記時感到已針對長期理解片遠優於具型別附註。

與透過傳統的具型別的鍵盤輸入這些優點的墨水,想像一下是否您無法進行筆跡只要畫筆紙張和控管裝置上執行動作就無法在真實世界中電腦的處理能力。數位筆墨,您可以輕鬆地變更色彩和筆墨外觀的只是想在真實世界中而拿進一步、 分析與內容的墨水來提供中繼資料,或將筆墨轉換成其他內容如文字、 圖形或命令。這提供您日常的筆記本,進行數位筆墨繪圖、 筆記、 註解和互動應用程式中的強大工具無法複寫至筆跡的全新維度。啟用畫筆與觸控裝置市場上繼續展開,筆跡會成為使用者和應用程式開發人員互動的關鍵方法。

在 Windows 10 是讓您輕鬆地將數位筆跡到您的應用程式透過 DirectInk 平台。DirectInk 提供一組豐富且可延伸 Windows 執行階段 (WinRT) Api 可讓您收集、 轉譯和管理通用 Windows 平台應用程式中的筆墨。藉由使用 DirectInk,得到相同的絕佳筆墨和 Microsoft 最新瀏覽器通用 OneNote 和手寫面板所使用的效能。以下是 DirectInk 提供您的應用程式的功能的快速概觀:

  • 美麗的筆墨: DirectInk 會使用輸入平滑處理和轉譯演算法的貝茲永遠確保您的筆跡外觀清晰又美觀的觸控與畫筆輸入。
  • 低延遲、 記憶體不足: DirectInk 使用高優先順序的背景執行緒以確保筆墨輸入的預測一定是立即而回應給使用者和管理資源有效降低您的應用程式的額外負荷。
  • 簡單且可延伸應用程式開發介面: 它們會提供可讓您建立豐富且複雜的功能在您的應用程式中的進階的功能與 DirectInk 提供可讓您快速地開始收集和管理筆墨,例如 InkCanvas 和 InkPresenter Api。

希望到目前為止您很興奮地開始使用您的應用程式中的數位筆跡。現在我將探討如何在您的應用程式中運用 DirectInk 平台並讓使用者很棒的筆跡體驗。

收集應用程式中的筆墨

若要開始使用數位筆墨,第一個步驟是設定的介面可以收集和呈現筆墨為輸入。在 Windows 8.1 市集應用程式帶到您的應用程式的手寫筆跡功能是涉及建立一個畫布接聽輸入事件,以及如何建立和轉譯筆劃--逐一使用自己的轉譯程式碼擴充程序。Windows 通用應用程式開始收集筆墨就跟 InkCanvas 放入您的應用程式一樣簡單:

<Grid>
  <InkCanvas x:Name="myInkCanvas"/>
</Grid>

您可以看到在 [圖 1, ,此單行程式碼可讓您開始收集畫筆輸入和輸入為黑色的鋼珠筆的呈現透明重疊。畫筆橡皮擦] 按鈕也會清除方面接觸的任何收集的筆墨。雖然這是絕佳的入門筆跡,如果您要變更筆跡收集或顯示如何?

使用 InkCanvas 收集類似黑色鋼珠畫筆筆墨
[圖 1 使用 InkCanvas 收集類似黑色鋼珠畫筆筆墨

您可以透過 InkCanvas 存取您 InkPresenter,公開控制的外觀和您筆墨的輸入的組態的功能。雖然畫筆輸入提供的手寫筆跡功能最佳的 UX,許多系統不會隨附配備畫筆。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

模擬使用 InkPresenter DrawingAttributes 書法筆刷
[圖 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 示範如何使用未處理輸入事件進行選取 lasso (如所示 [圖 4) 選取螢幕上的筆劃。

[圖 3 使用未處理輸入的事件選取範圍 Lasso

...
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);
}

選取與 Lasso 筆劃
[圖 4 選取與 Lasso 筆劃

您選取筆劃後,您可以使用 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();
  }
}

清除已在您 InkStrokeContainer 筆劃並從 ISF 檔或 GIF 檔案內嵌 ISF 資料載入一組新筆劃的 LoadAsync 會執行相反的函式。筆劃會載入 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 事件之前。

當事件標示為 Handled 時,DirectInk 將會停止處理筆劃,而且它如果筆劃已同處理序,將會取消並從螢幕中移除。您需要時使用這些事件,不過要小心。因為它們在 DirectInk 背景執行緒,而非 UI 執行緒上發生,任何大量處理您事件或等候例如 UI 執行緒可能會導致延隔時間會影響您筆墨的回應速度較慢的執行緒中執行的活動中。

自訂乾 DirectInk 的最複雜的功能之一就是自訂乾燥的模式,可讓您的應用程式呈現和管理已完成或"乾"筆墨筆劃上同時處理進行中的高效能轉譯 DirectInk 並可讓您自己 DirectX 介面或"濕"筆墨筆劃。雖然 DirectInk 的預設乾燥模式可以處理大部分的情況下您可能想要啟用應用程式中,少數的案例需要您獨立管理筆墨:

  • 筆跡和非筆墨的內容 (文字、 圖形) 交錯維持疊置順序
  • 高效能移動瀏覽和縮放在大型的筆墨畫布上有大量的筆墨筆劃
  • 同步到像是直線或圖形的 DirectX 物件乾燥筆墨

在 Windows 10 自訂乾燥模式支援 SurfaceImageSource (SIS) 或 VirtualSurfaceImageSource (VSIS) 與同步處理。SIS 及 VSIS 提供您的應用程式內繪製和撰寫,DirectX 共用的介面雖然 VSIS 提供大於之畫面的高效能移動瀏覽和縮放虛擬介面。因為到這些介面上的視覺效果更新系統同步處理到 XAML UI 執行緒,SIS 或 VSIS 呈現筆墨時也可以從 DirectInk 濕層同時移除。自訂 Drying 也支援乾燥筆墨 SwapChainPanel,但並不保證同步處理。因為 SwapChainPanel 不與 UI 執行緒同步處理,會有間小的重疊您 SwapChainPanel 和筆跡移除從 DirectInk 濕的墨水層次時呈現筆墨時。

當您啟動自訂乾燥時,您可以以更細微的控制許多 DirectInk 所提供的功能預設會讓您建置邏輯如何筆墨會轉譯和會從您乾介面清除並判斷您的應用程式所管理筆墨筆劃資料的方式。為了協助您建立這項功能,許多 DirectInk 元件都可做為獨立物件來填滿間距協助您的應用程式項目。當啟動自訂乾燥時,DirectInk 提供 InkSynchronizer 物件可讓您開始和結束乾燥程序以便筆墨都被移除了 DirectInk 濕圖層與同步處理時將它加入至您自訂的乾層。還有可透過確保一致濕和乾層之間筆墨外觀的 InkD2DRender DirectInk 預設乾墨水呈現邏輯。以清除,您可以使用未處理輸入事件來建置基礎的清除邏輯類似於先前的範例。

如需詳細資訊和使用自訂乾燥的範例,查看在 github ComplexInk 範例 bit.ly/1NkRjt7

開始建立用筆墨

使用您所學到目前為止有關 InkCanvas、 InkPresenter 和 InkStrokeContainer,您可以現在收集筆墨的不同類型的輸入、 自訂存取筆劃資料畫面上的筆墨的顯示方式和筆劃資料的變更會反映在 DirectInk 所呈現的筆墨筆劃。您可以使用簡單的層級之功能,建置各種不同的使用者互動,從簡單用筆記和收集使用者的簽章等較多案例為主的功能。您也可以建置更複雜的互動透過獨立的輸入事件和自訂乾燥模式 InkRecognizerContainer 的工具。

使用這些工具可供使用,您的應用程式應該能夠運用所有數位筆跡可以提供給您的使用者提供絕佳的筆跡經驗的優點。隨著畫筆與觸控功能的裝置數目持續增加,對客戶提供絕佳的筆跡經驗會變得更為重要的使用者滿意度和應用程式的差異。希望您可能需要一些時間才能認為有關如何數位筆跡可以在您的應用程式中工作並開始體驗 DirectInk。

最後一提,筆跡仍然是 Microsoft 的投資的重要區域以及其中一個要改善的最大索引鍵和擴充未來版本的 DirectInk 平台是我們的開發人員社群的意見。如果您開發與 DirectInk 時有任何問題、 註解或意見,來信請寄至 DirectInk@microsoft.com


Connor Weins是使用 [畫筆] 手寫筆和筆跡 Windows 開發人員生態系統平台群組中的小組的專案經理。與他連絡 conwei@microsoft.com

感謝以下的微軟技術專家對本文的審閱: Krishnan Menon 和 Xiao Tu
Krishnan Menon 是 Windows 核心輸入平台小組的資深軟體工程師。Windows 10 他曾在設計和開發的畫筆和筆跡 DirectInk 平台和通用的 Windows 應用程式開發介面。

Xiao Tu 是 Windows 核心輸入平台小組的主要軟體工程。Windows 10 他一直致力於提供通用的 Windows 平台 Api 的畫筆和筆跡。他自 2004年已與 Microsoft 和一直致力於 Win32 筆墨平台、 Windows Presentation Foundation (WPF) 筆墨平台、 Windows 7 和 8 的多點觸控平台和 IE 11 指標輸入和高 DPI 的支援。