The Image
- Chromatic adaptation (color shifting) for images, which allows images designed for light themes to be automatically adjusted for use in dark themes.
- Converting a monochrome vector image to render in the current foreground color.
- Dynamic loading of pre-defined high-DPI and/or theme-specific image variations for raster images.
- Conversion of images to grayscale.
- Conversion of images to monochrome, in a specified color.
While all the image adaptation logic is contained within the Image
A single BitmapImage that is altered to show normal, disabled, monochrome, and monochrome disabled states in both light and dark themes
Usage Scenarios for Image Provider
Common scenarios for using an image provider (and generally DynamicImage controls) are:
- Your application designed images for a light theme and you want them adapted to look good in a dark theme.
- You have monochrome vector icons and want to render them in the current foreground color instead of their designed color.
- You wish to support alternate scaled variations of raster images that automatically apply themselves when the application's DPI changes.
- You wish to support predesigned variations of raster images designed for specific themes, that are automatically applied when those themes become active.
- You want images adapted to grayscale.
- You want images adapted to monochrome.
DynamicImage and ImageProvider
The DynamicImage control calls into the ImageImageSource
set to its Source
property.
It watches for theme and DPI changes and updates the image source adaptation appropriately.
Note that the native Image
control from which DynamicImage inherits does not include any functionality to interact with Image
Assigning a Non-Default Image Provider to an ImageSource
An Image
When the DynamicImage control needs to adapt an image, it examines the ImageSource
set to its Source
property to see if a value is returned for the ImageProvider.Provider
attached property. If no specific ImageImageSource
, then the static instance returned via Image
The following example shows how a non-default ImageImageProviders.ChromaticAdaptation
class in your application could be applied to a DrawingImage
. The DrawingImage
will then use that non-default image provider for its adaptation logic instead of the one available via Image
To sum up, if you want all the DynamicImage control instances in your application to use the same image provider configuration, simply set that configuration on the ImageImageSource
via the ImageProvider.Provider
attached property.
Chromatic Adaptation for Dark Themes
Chromatic adaptation is the process of converting colors in an image so that they render well on a specific background color. This is especially useful when your application has images designed for a light theme, and you wish for your application to support a dark theme. Image provider can automatically convert them for you so that you don't have to design dark theme variations.
The following example shows the configuration for an ImageDark
, Black
, etc.). The source images should be designed for a light theme and use a minimal number of colors (i.e., avoid gradients).
Chromatic Adaptation for All Themes
Chromatic adaptation can also be applied in all themes.
The following example shows the configuration for an Image
While the ImageChromaticAdaptationMode.Always
mode is supported, it's generally enough to use the DarkThemes
mode instead. DarkThemes
mode doesn't perform any adaptation processing when in light themes.
Predefined Monochrome Vector Image Adaptation
Vector images designed in a single color (monochrome) can be adapted to render using the DynamicImage control's current foreground color. This feature is extremely useful when vector images need to be used on a variety of controls, each with different foregrounds and backgrounds.
The following example shows the configuration for an Image
Alternate Raster Image Scale Variations
Raster images render blurry when used in high-DPI. DynamicImage can automatically watch for high-DPI scenarios and swap in an image variation designed for high-DPI.
The image provider knows to support specific scales when scale values higher than 1.0
are added to its Scales collection. Note that if you do add a scale to the collection, you must ensure that each image design has a <filename>.Scale-<scalefactor>.<fileextension>
image available in the same folder as the source image.
The following example shows the configuration for an Image
The above configuration will have DynamicImage watch for high-DPI scenarios and will have it adapt to swap in an image located at "/Images/Save32.Scale-200.png"
when entering DPI greater than 100%.
No .Scale-100
should be in the filenames of images designed for 100% DPI.
Note
When using scale variations, it's important to set the Width
and Height
properties on the DynamicImage control to ensure that a swapped-in high-DPI image will not resize the control itself from its intended device independent unit size. For instance, an image designed for 32x32 size should have the Width
and Height
both set to 32
, even if a 64x64 200% DPI image variation is swapped in.
Alternate Raster Image Theme Variations
Raster images might have other specific designs when in certain themes. DynamicImage can automatically watch for theme changes and swap in an image variation designed for that theme. This feature should not be used if you are making use of chromatic adaptation, since these theme variations are already designed for a specific theme and no adaptation is necessary.
The image provider knows to support specific themes when theme names are added to its Theme<filename>.Theme-<themename>.<fileextension>
image available in the same folder as the source image.
The following example shows the configuration for an Image
The above configuration will have DynamicImage watch for theme changes and will have it adapt to swap in an image located at "/Images/Save32.Theme-Dark.png"
when theme named "Dark" is activated.
Theme name and scale variations can be combined as well. In cases where both variations are supported by an image provider and need to load, the image file <filename>.Theme-<themename>.Scale-<scalefactor>.<fileextension>
will be loaded.
No .Theme-<defaultthemename>
should be in the filenames of images designed for your application's default theme.
Grayscale Adaptation
Images are often converted to grayscale when their containing controls are disabled.
The following example shows a DynamicImage containing an image that will render in semi-transparent grayscale when disabled.
Monochrome Adaptation
Images are often converted to monochrome when displayed on intense backgrounds, or when going for a flat appearance.
The following example shows a DynamicImage containing a raster image that will render in monochrome. The monochrome color will match the color derived from the inherited foreground property.
The following example shows a DynamicImage containing a raster image that will render in monochrome. The monochrome color will be red.
High-Contrast Themes
Images can be automatically converted to monochrome when in high-contrast themes if the Imagetrue
.
Preventing Portions of an Image from Being Adapted
Sometimes a DrawingImage
may include portions within it that should not be adapted.
A common scenario of this case is a fill color image, where the image shows a paint bucket and a swatch rectangle underneath it that contains the current foreground color. For this scenario, we only want the root portion of the image (the paint bucket) to be adapted and we do not want the swatch rectangle to be touched by adaptation logic in any way.
To prevent adaptation on an ImageSource
, or a Drawing
within a DrawingImage
, set the attached ImageProvider.CanAdapt
property to false
on that object. It will be skipped during the image adaptation process.
The following example shows how the attached ImageProvider.CanAdapt
property can be used to prevent an entire image from being adapted.
Adjusting the Scheme for Locating Scale and Theme Raster Image Variations
The ImageUri
is passed in and possibly adjusted based on the ImageUri
.
The default implementation of that method calls into the Get"Scale-200"
if the image provider supports 200% scale (via Scales) and the Image2.0
. The Get"Theme-Dark"
if the image provider supports the "Dark" theme (via Theme"Dark"
. Either of those methods may be overridden if another naming scheme is desired.
As an example, if the image provider indicates that it supports a specific raster image for 200% scale and "Dark" theme, passing in "Save32.png"
to Transform"Save32.Theme-Dark.Scale-200.png"
result. This alternate Uri
will be loaded and used as the base for any other adaptations (chromatic, grayscale, monochrome) that need to take place.