Skip to content

Commit

Permalink
Merge pull request #599 from leocb/patch-1
Browse files Browse the repository at this point in the history
Update image.md with information about support for blend modes
  • Loading branch information
maxkatz6 authored Feb 17, 2025
2 parents d869112 + 1ba5445 commit f49541d
Show file tree
Hide file tree
Showing 35 changed files with 164 additions and 1 deletion.
142 changes: 142 additions & 0 deletions docs/concepts/blend-modes.md
Original file line number Diff line number Diff line change
@@ -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
<Panel>
<Image Source="./Cat.jpg"/>
<Image Source="./Overlay-Color.png" BlendMode="Multiply"/>
</Panel>
```

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) |
|:---:|:---:|
| <img src={BlendModeCat} alt="" width="180"/> | <img src={BlendModeOverlayColor} alt="" width="180"/> |

Below are all the values currently supported by Avalonia

| Preview | Enum | Description |
|---|---|---|
| <img src={BlendModeNothing} alt="" width="180"/> | `Unspecified` | or `SourceOver` - Default Behavior. |
| <img src={BlendModePlus} alt="" width="180"/> | `Plus` | Display the sum of the source image and destination image. |
| <img src={BlendModeScreen} alt="" width="180"/> | `Screen` | Multiplies the complements of the destination and source color values, then complements the result. |
| <img src={BlendModeOverlay} alt="" width="180"/> | `Overlay` | Multiplies or screens the colors, depending on the destination color value. |
| <img src={BlendModeDarken} alt="" width="180"/> | `Darken` | Selects the darker of the destination and source colors. |
| <img src={BlendModeLighten} alt="" width="180"/> | `Lighten` | Selects the lighter of the destination and source colors. |
| <img src={BlendModeColorDodge} alt="" width="180"/> | `ColorDodge` | Darkens the destination color to reflect the source color. |
| <img src={BlendModeColorBurn} alt="" width="180"/> | `ColorBurn` | Multiplies or screens the colors, depending on the source color value. |
| <img src={BlendModeHardLight} alt="" width="180"/> | `HardLight` | Darkens or lightens the colors, depending on the source color value. |
| <img src={BlendModeSoftLight} alt="" width="180"/> | `SoftLight` | Subtracts the darker of the two constituent colors from the lighter color. |
| <img src={BlendModeDifference} alt="" width="180"/> | `Difference` | Produces an effect similar to that of the Difference mode but lower in contrast. |
| <img src={BlendModeExclusion} alt="" width="180"/> | `Exclusion` | The source color is multiplied by the destination color and replaces the destination|
| <img src={BlendModeMultiply} alt="" width="180"/> | `Multiply` | Creates a color with the hue of the source color and the saturation and luminosity of the destination color. |
| <img src={BlendModeHue} alt="" width="180"/> | `Hue` | Creates a color with the hue of the source color and the saturation and luminosity of the destination color. |
| <img src={BlendModeSaturation} alt="" width="180"/> | `Saturation` | Creates a color with the saturation of the source color and the hue and luminosity of the destination color. |
| <img src={BlendModeColor} alt="" width="180"/> | `Color` | Creates a color with the hue and saturation of the source color and the luminosity of the destination color. |
| <img src={BlendModeLuminosity} alt="" width="180"/> | `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) |
|:---:|:---:|
| <img src={BlendModeA} alt="" width="180"/> | <img src={BlendModeB} alt="" width="180"/> |

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 |
|---|---|---|
| <img src={BlendModeSource} alt="" width="180"/> | `Source` | Only the source will be present. |
| <img src={BlendModeSourceOver} alt="" width="180"/> | `SourceOver` | or `Unspecified` - Default behavior, Source is placed over the destination. |
| <img src={BlendModeSourceIn} alt="" width="180"/> | `SourceIn` | The source that overlaps the destination, replaces the destination. |
| <img src={BlendModeSourceOut} alt="" width="180"/> | `SourceOut` | Source is placed, where it falls outside of the destination. |
| <img src={BlendModeSourceAtop} alt="" width="180"/> | `SourceAtop` | Source which overlaps the destination, replaces the destination. |
| <img src={BlendModeXor} alt="" width="180"/> | `Xor` | The non-overlapping regions of source and destination are combined. |
| <img src={BlendModeDestination} alt="" width="180"/> | `Destination` | Only the destination will be present. |
| <img src={BlendModeDestinationOver} alt="" width="180"/> | `DestinationOver` | Destination is placed over the source. |
| <img src={BlendModeDestinationIn} alt="" width="180"/> | `DestinationIn` | Destination which overlaps the source, replaces the source. |
| <img src={BlendModeDestinationOut} alt="" width="180"/> | `DestinationOut` | Destination is placed, where it falls outside of the source. |
| <img src={BlendModeDestinationAtop} alt="" width="180"/> | `DestinationAtop` | Destination which overlaps the source replaces the source. |
22 changes: 21 additions & 1 deletion docs/reference/controls/image.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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:

Expand All @@ -35,6 +40,8 @@ This example shows a bitmap asset loaded into an image control where the height

<img src={ImageUnscaledScreenshot} alt="" />

### 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
Expand All @@ -48,6 +55,19 @@ In this next example, introducing the stretch setting `UniformToFill` fits in al

<img src={ImageUniformToFillScreenshot} alt="" />

### 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
<Panel>
<Image Source="./Cat.jpg"/>
<Image Source="./Overlay-Color.png" BlendMode="Multiply"/>
</Panel>
```

<img src={BlendModeMultiply} alt="" width="350"/>

## More Information

:::info
Expand Down
1 change: 1 addition & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ const sidebars = {
],
},
'concepts/image-interpolation',
'concepts/blend-modes',
'concepts/templated-controls',
'concepts/themes',
'concepts/ui-composition',
Expand Down
Binary file added static/img/concepts/blend/A.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/B.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Cat.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Color.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/ColorBurn.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/ColorDodge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Darken.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Destination.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/DestinationAtop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/DestinationIn.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/DestinationOut.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/DestinationOver.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Difference.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Exclusion.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/HardLight.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Hue.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Lighten.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Luminosity.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Multiply.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Nothing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Overlay-Color.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Overlay.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Plus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Saturation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/Screen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/concepts/blend/SoftLight.png
Binary file added static/img/concepts/blend/Source.png
Binary file added static/img/concepts/blend/SourceAtop.png
Binary file added static/img/concepts/blend/SourceIn.png
Binary file added static/img/concepts/blend/SourceOut.png
Binary file added static/img/concepts/blend/SourceOver.png
Binary file added static/img/concepts/blend/Xor.png

0 comments on commit f49541d

Please sign in to comment.