diff --git a/images/premultiplied-example-1.png b/images/premultiplied-example-1.png new file mode 100644 index 00000000000..841b29e7fbc Binary files /dev/null and b/images/premultiplied-example-1.png differ diff --git a/images/premultiplied-example-2.png b/images/premultiplied-example-2.png new file mode 100644 index 00000000000..b679083c513 Binary files /dev/null and b/images/premultiplied-example-2.png differ diff --git a/images/premultiplied-example-3.png b/images/premultiplied-example-3.png new file mode 100644 index 00000000000..6403becb387 Binary files /dev/null and b/images/premultiplied-example-3.png differ diff --git a/images/premultiplied-example-4.png b/images/premultiplied-example-4.png new file mode 100644 index 00000000000..3187a8d36ee Binary files /dev/null and b/images/premultiplied-example-4.png differ diff --git a/images/premultiplied-example-5.png b/images/premultiplied-example-5.png new file mode 100644 index 00000000000..a998d87c61b Binary files /dev/null and b/images/premultiplied-example-5.png differ diff --git a/source b/source index e890e004aed..4b005e83ea1 100644 --- a/source +++ b/source @@ -64025,7 +64025,7 @@ try { data-x="">sy+sh), (sx, sy+sh), in the bitmap's coordinate space units. Pixels outside the output bitmap must be set to transparent black. Pixel - values must not be premultiplied by alpha.

+ values must not be premultiplied by alpha.

When the user agent is required to create an ImageData object, given a positive integer number of rows rows, a positive integer number of pixels per row @@ -64167,10 +64167,11 @@ try { in the rendering context's output bitmap.

-

Due to the lossy nature of converting to and from premultiplied alpha color - values, pixels that have just been set using putImageData() might be returned to an equivalent - getImageData() as different values.

+

Due to the lossy nature of converting to and from premultiplied alpha color values, pixels that have + just been set using putImageData(), and are not + completely opaque, might be returned to an equivalent getImageData() as different values.

The current path, transformation matrix, shadow attributes, global @@ -65740,6 +65741,96 @@ interface OffscreenCanvasRenderingContext2D { +

Premultiplied alpha and the 2D rendering context
+ +

Premultiplied alpha refers to one way of + representing transparency in an image, the other being non-premultiplied alpha.

+ +

Under non-premultiplied alpha, the red, green, and blue channels of a pixel represent that + pixel's color, and its alpha channel represents that pixel's opacity.

+ +

Under premultiplied alpha, however, the red, green, and blue channels of a pixel represent the + amounts of color that the pixel adds to the image, and its alpha channel represents the amount + that the pixel obscures whatever is behind it.

+ +
+

For instance, assuming the color channels range from 0 (off) to 255 (full intensity), these + example colors are represented in the following ways:

+ + + + + + + + + + + +
CSS color representation + Premultiplied representation + Non-premultiplied representation + Description of color + Image of color blended above other content +
rgba(255, 127, 0, 1) + 255, 127, 0, 255 + 255, 127, 0, 255 + Completely-opaque orange + An opaque orange circle sits atop a background +
rgba(255, 255, 0, 0.5) + 127, 127, 0, 127 + 255, 255, 0, 127 + Halfway-opaque yellow + A yellow circle, halfway transparent, sits atop a background +
Unrepresentable + 255, 127, 0, 127 + Unrepresentable + Additive halfway-opaque orange + An orange circle somewhat brightens the background that it sits atop +
Unrepresentable + 255, 127, 0, 0 + Unrepresentable + Additive fully-transparent orange + An orange circle completely brightens the background that it sits atop +
rgba(255, 127, 0, 0) + 0, 0, 0, 0 + 255, 127, 0, 0 + Fully-transparent ("invisible") orange + An empty background with nothing atop it +
rgba(0, 127, 255, 0) + 0, 0, 0, 0 + 255, 127, 0, 0 + Fully-transparent ("invisible") turquoise + An empty background with nothing atop it +
+
+ +

Converting a color value from a non-premultiplied + representation to a premultiplied one involves multiplying the color's red, green, and + blue channels by its alpha channel (remapping the range of the alpha channel such that "fully + transparent" is 0, and "fully opaque" is 1).

+ +

Converting a color value from a premultiplied + representation to a non-premultiplied one involves the inverse: dividing the color's red, + green, and blue channels by its alpha channel.

+ +

As certain colors can only be represented under premultiplied alpha (for instance, additive + colors), and others can only be represented under non-premultiplied alpha (for instance, + "invisible" colors which hold certain red, green, and blue values even with no opacity); and + division and multiplication on 8-bit integers (which is how canvas' colors are currently stored) + entails a loss of precision, converting between premultiplied and non-premultiplied alpha is a + lossy operation on colors that are not fully opaque.

+ +

A CanvasRenderingContext2D's output bitmap and an + OffscreenCanvasRenderingContext2D's bitmap must use premultiplied alpha to represent transparent colors.

+ +

It is important for canvas bitmaps to represent colors using premultiplied alpha + because it affects the range of representable colors. While additive colors cannot currently be + drawn onto canvases directly because CSS colors are non-premultiplied and cannot represent them, + it is still possible to, for instance, draw additive colors onto a WebGL canvas and then draw that + WebGL canvas onto a 2D canvas via drawImage().

+

Custom elements

Introduction

@@ -94710,7 +94801,7 @@ dictionary ImageBitmapOptions { if the premultiplyAlpha option is set to "premultiply", the bitmap data's color channels are - premultiplied by its alpha channel. + premultiplied by its alpha channel.

Rejects the promise with an "InvalidStateError" DOMException if the source image is not in a valid state (e.g., an img @@ -95150,14 +95241,15 @@ dictionary ImageBitmapOptions { optimal for drawing images onto the canvas.

  • If val is "premultiply", the output - that is not premultiplied by alpha must have its color components multiplied by alpha and - that is premultiplied by alpha must be left untouched.

  • + data-x="dom-PremultiplyAlpha-premultiply">premultiply", the output that + is not premultiplied by alpha must have its color components multiplied by alpha and that is premultiplied by alpha + must be left untouched.

  • If val is "none", the output that is not - premultiplied by alpha must be left untouched and that is premultiplied by alpha must have - its color components divided by alpha.

  • + premultiplied by alpha must be left untouched and that is premultiplied by alpha must have its + color components divided by alpha.