diff --git a/docs/concepts/blend-modes.md b/docs/concepts/blend-modes.md new file mode 100644 index 000000000..f978a5c4f --- /dev/null +++ b/docs/concepts/blend-modes.md @@ -0,0 +1,142 @@ +--- +title: Bitmap Blend Modes +description: CONCEPTS +--- + +import BlendModeCat from '/img/concepts/blend/Cat.jpg'; +import BlendModeOverlayColor from '/img/concepts/blend/Overlay-Color.png'; + +import BlendModeOverlay from '/img/concepts/blend/Overlay.png'; +import BlendModePlus from '/img/concepts/blend/Plus.png'; +import BlendModeSaturation from '/img/concepts/blend/Saturation.png'; +import BlendModeScreen from '/img/concepts/blend/Screen.png'; +import BlendModeSoftLight from '/img/concepts/blend/SoftLight.png'; +import BlendModeColor from '/img/concepts/blend/Color.png'; +import BlendModeColorBurn from '/img/concepts/blend/ColorBurn.png'; +import BlendModeColorDodge from '/img/concepts/blend/ColorDodge.png'; +import BlendModeDarken from '/img/concepts/blend/Darken.png'; +import BlendModeDifference from '/img/concepts/blend/Difference.png'; +import BlendModeExclusion from '/img/concepts/blend/Exclusion.png'; +import BlendModeHardLight from '/img/concepts/blend/HardLight.png'; +import BlendModeHue from '/img/concepts/blend/Hue.png'; +import BlendModeLighten from '/img/concepts/blend/Lighten.png'; +import BlendModeLuminosity from '/img/concepts/blend/Luminosity.png'; +import BlendModeMultiply from '/img/concepts/blend/Multiply.png'; +import BlendModeNothing from '/img/concepts/blend/Nothing.png'; + +import BlendModeA from '/img/concepts/blend/A.png'; +import BlendModeB from '/img/concepts/blend/B.png'; + +import BlendModeDestination from '/img/concepts/blend/Destination.png'; +import BlendModeDestinationAtop from '/img/concepts/blend/DestinationAtop.png'; +import BlendModeDestinationIn from '/img/concepts/blend/DestinationIn.png'; +import BlendModeDestinationOut from '/img/concepts/blend/DestinationOut.png'; +import BlendModeDestinationOver from '/img/concepts/blend/DestinationOver.png'; +import BlendModeSource from '/img/concepts/blend/Source.png'; +import BlendModeSourceAtop from '/img/concepts/blend/SourceAtop.png'; +import BlendModeSourceIn from '/img/concepts/blend/SourceIn.png'; +import BlendModeSourceOut from '/img/concepts/blend/SourceOut.png'; +import BlendModeSourceOver from '/img/concepts/blend/SourceOver.png'; +import BlendModeXor from '/img/concepts/blend/Xor.png'; + +When rendering bitmaps graphics on screen, Avalonia supports specifying what blend mode to use while rendering. Blend modes changes the calculations performed when drawing new pixels (source) over existing pixels (destination). + +Currently Avalonia Composite modes and Pixel Blend modes are located in a single enum called `BitmapBlendingMode`. + +Composite modes enums mainly describes how the new pixels interact with the current on-screen pixels according to the alpha channel, this can be used to create, for example: "cookie cutters", exclusion zones or masks. + +Pixel Blend modes on the other hand, specifies how the new colors will interact with the current colors. These modes can be used for example: on special effects, change color hues or other more complex image compositions. + +See the [Wikipedia page](https://en.wikipedia.org/wiki/Blend_modes) on blend modes for examples of how they work and the math behind them. + +:::info +Currently Avalonia only supports Blend Modes when using the Skia renderer. Trying to use these modes with the D2D renderer will result in the same behavior as the default mode. +::: + +## Default Behavior + +The default blend mode is `SourceOver`, meaning replacing all pixels values by the new values, dictated by the alpha channel. This is the standard way most applications overlay two images. + +## How to use it + +In XAML, you can specify what blend mode to use when rendering a Image control. The following example will render a color overlay over the picture of a very cute cat: + +```xml + + + + +``` + +If you're creating a Custom User control and want to render a bitmap with code using one of these modes, you can do so by setting the `BitmapBlendingMode` in the control context render options: + +``` csharp +// Inside the "Render" method, draw the bitmap like this: + +using (context.PushRenderOptions(RenderOptions with { BitmapBlendingMode = BitmapBlendingMode.Multiply })) +{ + context.DrawImage(source, sourceRect, destRect); +} +``` + +## Bitmap Blend Mode Gallery + +Avalonia supports several bitmap blend modes that can be applied to rendering: + +### Pixel Blend Modes + +Pixel blend modes affect only the color without taking into consideration the alpha channel. + +These are the images used in the examples: + +| Cute Cat base image (destination) | Color Wheel overlay image (source) | +|:---:|:---:| +| | | + +Below are all the values currently supported by Avalonia + +| Preview | Enum | Description | +|---|---|---| +| | `Unspecified` | or `SourceOver` - Default Behavior. | +| | `Plus` | Display the sum of the source image and destination image. | +| | `Screen` | Multiplies the complements of the destination and source color values, then complements the result. | +| | `Overlay` | Multiplies or screens the colors, depending on the destination color value. | +| | `Darken` | Selects the darker of the destination and source colors. | +| | `Lighten` | Selects the lighter of the destination and source colors. | +| | `ColorDodge` | Darkens the destination color to reflect the source color. | +| | `ColorBurn` | Multiplies or screens the colors, depending on the source color value. | +| | `HardLight` | Darkens or lightens the colors, depending on the source color value. | +| | `SoftLight` | Subtracts the darker of the two constituent colors from the lighter color. | +| | `Difference` | Produces an effect similar to that of the Difference mode but lower in contrast. | +| | `Exclusion` | The source color is multiplied by the destination color and replaces the destination| +| | `Multiply` | Creates a color with the hue of the source color and the saturation and luminosity of the destination color. | +| | `Hue` | Creates a color with the hue of the source color and the saturation and luminosity of the destination color. | +| | `Saturation` | Creates a color with the saturation of the source color and the hue and luminosity of the destination color. | +| | `Color` | Creates a color with the hue and saturation of the source color and the luminosity of the destination color. | +| | `Luminosity` | Creates a color with the luminosity of the source color and the hue and saturation of the destination color. | + +### Composition Blend modes + +Composition blend modes affect only the alpha channel without messing with the colors. + +These are the images used in the examples: + +| "A" base image (destination) | "B" overlay image (source) | +|:---:|:---:| +| | | + +Below are all the values currently supported by Avalonia. Please note that this demo is sensitive to the alpha channel and therefore the website background bleed through the images. + +| Preview | Enum | Description | +|---|---|---| +| | `Source` | Only the source will be present. | +| | `SourceOver` | or `Unspecified` - Default behavior, Source is placed over the destination. | +| | `SourceIn` | The source that overlaps the destination, replaces the destination. | +| | `SourceOut` | Source is placed, where it falls outside of the destination. | +| | `SourceAtop` | Source which overlaps the destination, replaces the destination. | +| | `Xor` | The non-overlapping regions of source and destination are combined. | +| | `Destination` | Only the destination will be present. | +| | `DestinationOver` | Destination is placed over the source. | +| | `DestinationIn` | Destination which overlaps the source, replaces the source. | +| | `DestinationOut` | Destination is placed, where it falls outside of the source. | +| | `DestinationAtop` | Destination which overlaps the source replaces the source. | diff --git a/docs/reference/controls/image.md b/docs/reference/controls/image.md index d19570796..5a04f74a4 100644 --- a/docs/reference/controls/image.md +++ b/docs/reference/controls/image.md @@ -4,6 +4,7 @@ description: REFERENCE - Built-in Controls import ImageUnscaledScreenshot from '/img/reference/controls/image/image-unscaled.png'; import ImageUniformToFillScreenshot from '/img/reference/controls/image/image-uniform-to-fill.png'; +import BlendModeMultiply from '/img/concepts/blend/Multiply.png'; # Image @@ -15,13 +16,17 @@ The image can display raster images from a specified image source. The source ca Images can be used to compose the content of another control. For example, you can create a graphical button using image controls. +The image can be rendered in a few different blend modes, which changes the way the image interacts with what's behind it. see the [Bitmap Blend Modes](../../concepts/blend-modes.md) page for a list of all supported blend modes and an example gallery. + The image displayed can be resized and scaled. The default settings for scaling (uniform stretch in both directions) will result in the image being fitted to the size (width and/or height) given. :::info The scaling settings for an image are the same as for the view box, see the reference [here](./viewbox.md). ::: -## Example +## Examples + +### Basic This example shows a bitmap asset loaded into an image control where the height and width have been restricted, but the scaling settings remain defaulted. The image itself is not square, but the image width and height are set to the same value. The rectangle is included to give an idea of how the image has been scaled: @@ -35,6 +40,8 @@ This example shows a bitmap asset loaded into an image control where the height +### Stretch + In this next example, introducing the stretch setting `UniformToFill` fits in all the height of the image, but crops the width because it would otherwise be wider than specified. The image is not distorted by this treatment. ```xml @@ -48,6 +55,19 @@ In this next example, introducing the stretch setting `UniformToFill` fits in al +### BlendMode + +This example is using two images, where the second image is using the `Multiply` Blend mode. For more information, read the [Bitmap Blend Modes](../../concepts/blend-modes.md) page. + +```xml + + + + +``` + + + ## More Information :::info diff --git a/sidebars.js b/sidebars.js index 0d9f424fe..964cff277 100644 --- a/sidebars.js +++ b/sidebars.js @@ -523,6 +523,7 @@ const sidebars = { ], }, 'concepts/image-interpolation', + 'concepts/blend-modes', 'concepts/templated-controls', 'concepts/themes', 'concepts/ui-composition', diff --git a/static/img/concepts/blend/A.png b/static/img/concepts/blend/A.png new file mode 100644 index 000000000..fb3dacda4 Binary files /dev/null and b/static/img/concepts/blend/A.png differ diff --git a/static/img/concepts/blend/B.png b/static/img/concepts/blend/B.png new file mode 100644 index 000000000..13aaf23dd Binary files /dev/null and b/static/img/concepts/blend/B.png differ diff --git a/static/img/concepts/blend/Cat.jpg b/static/img/concepts/blend/Cat.jpg new file mode 100644 index 000000000..01de4614f Binary files /dev/null and b/static/img/concepts/blend/Cat.jpg differ diff --git a/static/img/concepts/blend/Color.png b/static/img/concepts/blend/Color.png new file mode 100644 index 000000000..b6e6b7c21 Binary files /dev/null and b/static/img/concepts/blend/Color.png differ diff --git a/static/img/concepts/blend/ColorBurn.png b/static/img/concepts/blend/ColorBurn.png new file mode 100644 index 000000000..1812a59ef Binary files /dev/null and b/static/img/concepts/blend/ColorBurn.png differ diff --git a/static/img/concepts/blend/ColorDodge.png b/static/img/concepts/blend/ColorDodge.png new file mode 100644 index 000000000..ff12a5d50 Binary files /dev/null and b/static/img/concepts/blend/ColorDodge.png differ diff --git a/static/img/concepts/blend/Darken.png b/static/img/concepts/blend/Darken.png new file mode 100644 index 000000000..c6edbe00c Binary files /dev/null and b/static/img/concepts/blend/Darken.png differ diff --git a/static/img/concepts/blend/Destination.png b/static/img/concepts/blend/Destination.png new file mode 100644 index 000000000..bcb03de2e Binary files /dev/null and b/static/img/concepts/blend/Destination.png differ diff --git a/static/img/concepts/blend/DestinationAtop.png b/static/img/concepts/blend/DestinationAtop.png new file mode 100644 index 000000000..1f0cea936 Binary files /dev/null and b/static/img/concepts/blend/DestinationAtop.png differ diff --git a/static/img/concepts/blend/DestinationIn.png b/static/img/concepts/blend/DestinationIn.png new file mode 100644 index 000000000..ebd1b2978 Binary files /dev/null and b/static/img/concepts/blend/DestinationIn.png differ diff --git a/static/img/concepts/blend/DestinationOut.png b/static/img/concepts/blend/DestinationOut.png new file mode 100644 index 000000000..ebf07dc00 Binary files /dev/null and b/static/img/concepts/blend/DestinationOut.png differ diff --git a/static/img/concepts/blend/DestinationOver.png b/static/img/concepts/blend/DestinationOver.png new file mode 100644 index 000000000..adda03eb8 Binary files /dev/null and b/static/img/concepts/blend/DestinationOver.png differ diff --git a/static/img/concepts/blend/Difference.png b/static/img/concepts/blend/Difference.png new file mode 100644 index 000000000..e9456b699 Binary files /dev/null and b/static/img/concepts/blend/Difference.png differ diff --git a/static/img/concepts/blend/Exclusion.png b/static/img/concepts/blend/Exclusion.png new file mode 100644 index 000000000..ced05f85e Binary files /dev/null and b/static/img/concepts/blend/Exclusion.png differ diff --git a/static/img/concepts/blend/HardLight.png b/static/img/concepts/blend/HardLight.png new file mode 100644 index 000000000..d6d56f99e Binary files /dev/null and b/static/img/concepts/blend/HardLight.png differ diff --git a/static/img/concepts/blend/Hue.png b/static/img/concepts/blend/Hue.png new file mode 100644 index 000000000..832793eb1 Binary files /dev/null and b/static/img/concepts/blend/Hue.png differ diff --git a/static/img/concepts/blend/Lighten.png b/static/img/concepts/blend/Lighten.png new file mode 100644 index 000000000..9f0ae673f Binary files /dev/null and b/static/img/concepts/blend/Lighten.png differ diff --git a/static/img/concepts/blend/Luminosity.png b/static/img/concepts/blend/Luminosity.png new file mode 100644 index 000000000..f772c5ce3 Binary files /dev/null and b/static/img/concepts/blend/Luminosity.png differ diff --git a/static/img/concepts/blend/Multiply.png b/static/img/concepts/blend/Multiply.png new file mode 100644 index 000000000..5fc0c9360 Binary files /dev/null and b/static/img/concepts/blend/Multiply.png differ diff --git a/static/img/concepts/blend/Nothing.png b/static/img/concepts/blend/Nothing.png new file mode 100644 index 000000000..4a5f0ea2a Binary files /dev/null and b/static/img/concepts/blend/Nothing.png differ diff --git a/static/img/concepts/blend/Overlay-Color.png b/static/img/concepts/blend/Overlay-Color.png new file mode 100644 index 000000000..ef464dedb Binary files /dev/null and b/static/img/concepts/blend/Overlay-Color.png differ diff --git a/static/img/concepts/blend/Overlay.png b/static/img/concepts/blend/Overlay.png new file mode 100644 index 000000000..843ce50f7 Binary files /dev/null and b/static/img/concepts/blend/Overlay.png differ diff --git a/static/img/concepts/blend/Plus.png b/static/img/concepts/blend/Plus.png new file mode 100644 index 000000000..ae159039b Binary files /dev/null and b/static/img/concepts/blend/Plus.png differ diff --git a/static/img/concepts/blend/Saturation.png b/static/img/concepts/blend/Saturation.png new file mode 100644 index 000000000..9744e24f8 Binary files /dev/null and b/static/img/concepts/blend/Saturation.png differ diff --git a/static/img/concepts/blend/Screen.png b/static/img/concepts/blend/Screen.png new file mode 100644 index 000000000..fe448fc3d Binary files /dev/null and b/static/img/concepts/blend/Screen.png differ diff --git a/static/img/concepts/blend/SoftLight.png b/static/img/concepts/blend/SoftLight.png new file mode 100644 index 000000000..d39c01f97 Binary files /dev/null and b/static/img/concepts/blend/SoftLight.png differ diff --git a/static/img/concepts/blend/Source.png b/static/img/concepts/blend/Source.png new file mode 100644 index 000000000..cbb139806 Binary files /dev/null and b/static/img/concepts/blend/Source.png differ diff --git a/static/img/concepts/blend/SourceAtop.png b/static/img/concepts/blend/SourceAtop.png new file mode 100644 index 000000000..33bdf8efc Binary files /dev/null and b/static/img/concepts/blend/SourceAtop.png differ diff --git a/static/img/concepts/blend/SourceIn.png b/static/img/concepts/blend/SourceIn.png new file mode 100644 index 000000000..f1989a2a7 Binary files /dev/null and b/static/img/concepts/blend/SourceIn.png differ diff --git a/static/img/concepts/blend/SourceOut.png b/static/img/concepts/blend/SourceOut.png new file mode 100644 index 000000000..a2975afd0 Binary files /dev/null and b/static/img/concepts/blend/SourceOut.png differ diff --git a/static/img/concepts/blend/SourceOver.png b/static/img/concepts/blend/SourceOver.png new file mode 100644 index 000000000..1438009f9 Binary files /dev/null and b/static/img/concepts/blend/SourceOver.png differ diff --git a/static/img/concepts/blend/Xor.png b/static/img/concepts/blend/Xor.png new file mode 100644 index 000000000..ee74b79f5 Binary files /dev/null and b/static/img/concepts/blend/Xor.png differ