page_type: sample languages:
- csharp products:
- windows-uwp statusNotificationTargets:
Coloring Book sample (updated to WinUI 2.4 - May 2020)
A mini-app that demonstrates the versatility of Windows Ink (including the Windows Ink Toolbar) and radial controller (for Wheel devices such as the Surface Dial) features.
Using the extensive customization features provided by the inking and radial controller APIs, this sample app incorporates coloring book functionality (line art, standard inking tools such as pen and pencil), a custom Ink Toolbar that features additional tools (flood fill, touch inking, undo/redo), and a fully customized standalone color palette containing a much more extensive collection of colors.
The Coloring Book sample includes the following features:
- Windows Ink with improved ink rendering performance using the custom ink drying APIs
- Windows Ink Toolbar with various customizations
- RadialController support and customizations
- Ink strokes constrained to predefined regions (boundaries specified by the line art)
- Flood fill of predefined regions
- Ink stroke erase and ink region erase
- Ink undo and redo
- Custom color palette
- Print support
- Share and Export
- Process and add your own line art to the collection of coloring projects
This sample does not cover Windows Ink Analysis.
May 2020 update
The current version of this sample includes updates to support WinUI 2.4 (including ColorPicker, ProgressBar, and ProgressRing).
Note - This sample is targeted and tested for Windows 10, version 2004 (10.0; Build 19041), and Visual Studio 2019. If you prefer, you can use project properties to retarget the project(s) to Windows 10, version 1903 (10.0; Build 18362).
For a simpler inking sample, see Coloring Book V1.
March 2018 update
This version of the sample includes extensive architecture, code, and functional improvements over the previous version. These updates necessarily make the sample more complicated. For a simpler inking sample, see Coloring Book V1.
This sample requires Visual Studio 2019, the Microsoft.UI.Xaml 2.4 nuget package, and the latest version of the Windows 10 SDK. You can use the free Visual Studio Community Edition to build and run Windows Universal Platform (UWP) apps.
To get the latest updates to Windows and the development tools, and to help shape their development, join the Windows Insider Program.
Running the sample
There are two projects in the VS solution for this sample:
- ColoringBook (default) - the actual coloring book app.
- ColoringBookPreprocessingGenerator - a utility for processing your own line art for use in the ColoringBook app.
You can Start Debugging (F5) or Start Without Debugging (Ctrl+F5) to try it out. The app will run in the emulator or on physical devices.
Note: The platform target currently defaults to ARM, so be sure to change that to x64 or x86 if you want to test on a non-ARM device.
Code at a glance
Custom dry ink rendering canvas
By default, ink input is processed on a low-latency background thread and rendered "wet" as it is drawn. When the stroke is completed (pen or finger lifted, or mouse button released), the stroke is processed on the UI thread and rendered "dry" to the InkCanvas layer (above the application content and replacing the wet ink). Windows Ink enables you to override this behavior and completely customize the inking experience by custom drying the ink input and providing more efficient management of large, or complex, collections of ink strokes. For example code, see ColoringPage.xaml, ColoringPage.xaml.cs, and ColoringPageController.cs.
To resolve ink rendering issues when a user zooms in or out (or for any change in display DPI), we adjust the DPI scale of the dry ink canvas in in the ColoringPage.ScrollViewer_ViewChanged method.
- Flood fill tool.
- Custom pen and pencil tools with stroke size slider and stroke graphic (exposed to developers), and color palette removed and replaced with custom palette described later.
- Custom eraser button with two eraser modes: stroke erase and cell erase.
- Touch inking.
- See ColoringBookInkToolbar.xaml and ColoringBookInkToolbar.xaml.cs.
Custom color palette
- More extensive set of default colors.
- Always visible.
- Rich color picker on press and hold (or right button click for mouse).
- See ColorPalette.xaml and ColorPalette.xaml.cs.
Surface Dial (Wheel device) support
- Default InkToolbar integration.
- Custom Undo/Redo ink back stack.
- See RadialControlHelper.cs.
- Each operation uses a StartTransaction() call -> [operations] -> EndTransaction() process, which enables multiple operations to go into one Undo/Redo back stack item.
- Each operation implements the IUndoRedoOperation interface.
- See UndoRedo.cs.
- A 500 ms timer is started when a specific operation completes (such as inking, eraser, undo/redo).
- After the timer completes, and it has not been restarted by a new operation, the save function is called.
- See ColoringPageController.cs.
Sharing and export
- For exporting as a png file, we use RenderTargetBitmap to create an image of the combined content of a XAML visual tree (the ColoringCanvas object in this sample). This eliminates the need to manually composite the different layers of the canvas.
- For sharing we use the standard UWP Share contract.
- See ColoringExporter.cs.
Each ColoringBook coloring page is composed of 4 layers:
- The top layer is the line art image to be colored. This sits on top of everything to ensure ink does not cover the black lines of the image.
- The second layer is the wet ink canvas where ink is rendered as it’s drawn, but is not dried.
Important: The ink strokes are encapsulated in a SwapChainPanel. This creates a more complex composition tree where the ink input is not rendered on the top layer (the image) but is instead directly associated with the InkCanvas.
- The third layer is the dry canvas where the wet ink strokes are dried. Once a stroke has been dried it is removed from the wet ink canvas.
- Finally, the bottom layer is where flood fill changes are applied. This is a WriteableBitmap image.
Inking within cells
The ColoringBook sample includes a default set of line art images that have been pre-processed to identify coloring regions. The region boundaries are derived from the lines in the images and are used to constrain inking to the active region. Users can draw individual ink strokes with the pen or pencil tools, or use the flood fill tool for more immediate gratification. Once inking has started in a region, strokes are not rendered outside the boundary of that region.
Adding your own artwork
This sample includes the ColoringBookPreprocessingGenerator project, which is the utility we built to process line art for use in the ColoringBook app. You can use this utility for your own line art.
- In a single folder, create your line art images. We recommend greyscale images of two sizes: 2000 x 1125 for default resolution and 4000 x 2250 for high resolution.
- Name them imagename.png and imagenameHighResolution.png, respectively.
- Create a thumbnail image from your original images by creating a copy of your original image and resizing it to 255 x 127.
- Rename this file to imagename.thumbnail.
- Build and run the ColoringBookPreprocessingGenerator project.
- Process your line art images. There are two processing options: a. Convert white to transparent in image. This converts whites and grays to their corresponding opacity value for a png image. This is necessary to ensure the background of the coloring image is transparent for seeing the layers of the coloring canvas under the source image. b. Generate Preprocessing - this creates the cell dictionary that maps co-ordinates to cells.
- Add the output directory to the ColoringBook project under Assets/LibraryImages.
Issue: Ink bleeding into other regions when coloring near a boundary
Reason: Clipping ink points as they cross a boundary is not a trivial task and is beyond the scope of this sample.
- Pen interactions and Windows Ink in UWP apps
- Ink tutorial and related sample
- InkCanvas class
- InkToolbar class
- InkPresenter class