View the directory –>

harden

BlendMode has always been a character that LETS me see and hide, and there are dozens of modes that make my head turn when I see them. I’ve been trying to figure this out lately, like:

  • There seems to be no code to refer to;
  • I don’t seem to have any specific blog posts to refer to (other than translation of the original)
  • The biggest problem is that the effect you write is different from the description of the document. You can’t understand the effect of the four-color bar and the bird, which is the most deadly.

I wonder if you have encountered these problems.

Conditional summary

Say first official API: API. Flutter. Dev/flutter/dar… It looks detailed, but it doesn’t immediately get you started.

BlendMode is used in many places, and the so-called “conditional” here only means that in some local conditions, I feel some understanding, so as to record.

Demo Prerequisites

  • When drawing with Canvas, saveLayer and restore are in effect.

What is the BlendMode

Key points extracted from the official API:

  • The algorithm used when drawing on a canvas.
  • BlendMode is an enumeration, and each enumeration value represents an algorithm.
  • When drawing shapes or images on a canvas, different algorithms can be used to mix pixels.
  • Blending pixels? Who are you mixing? SRC and DST. Look at the diagram below.
  • SRC and DST are two layers of pixels on the screen, and BlendMode determines how the two layers of pixels overlap.

  • As shown in the figure, in the overlap between the box and the circle, the last overlay was drawn first, that is, 3 on top of 2 and 6 on top of 5.
  • Note that there is a bg with a red box that does not participate in the blendmode calculation. Only SRC and DST participate in the calculation.

Pay attention to

  • Graphical brightness, saturation and color, please understand, may refer to: jingyan.baidu.com/article/d2b…
  • Pattern explanation, also from the official API, will be added to some personal understanding

Those two dozen patterns

First look at the schematic, remember the figures representing SRC DST and BG:

The original code is as follows:

import 'package:flutter/material.dart'; import 'dart:math'; import 'dart:ui'; import 'dart:ui' as ui; import 'package:flutter/services.dart'; class TestPaintBlendMode extends StatefulWidget { @override State<StatefulWidget> createState() { return TestPaintState(); } } class TestPaintState extends State<TestPaintBlendMode> { ui.Image _src; ui.Image _dst; @override void initState() { super.initState(); _loadImage(); } void _loadImage() async { _src = await loadImageFromAssets('images/a2.png'); _dst = await loadImageFromAssets('images/dst.jpeg'); setState(() {}); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("test paint"), ), body: CustomPaint( painter: _MyPaint(_src, _dst), size: MediaQuery.of(context).size, ), backgroundColor: Colors.white, ); } Future<ui.Image> loadImageFromAssets(String path) async { ByteData data = await rootBundle.load(path); List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); return decodeImageFromList(bytes); } } class _MyPaint extends CustomPainter { ui.Image _src; ui.Image _dst; _MyPaint(this._src, this._dst); @override void paint(Canvas canvas, Size size) { // translateToCenter(canvas, size); print("size=" + size.width.toString() + " " + size.height.toString()); _test(canvas, size); } void _test(Canvas canvas, Size size) { Paint _paint = Paint(); _paint.isAntiAlias = true; canvas.drawPaint(_paint.. color = Colors.black12); Color = color.red; canvas.drawCircle(Offset(150, 100), 100, _paint); Canvas. SaveLayer (Offset. Zero & size, Paint()); Color = Colors. YellowAccent; canvas.drawCircle(Offset(250, 100), 100, _paint); DrawImage (_dst, Offset(0,550), _paint); _paint. BlendMode = blendmode. clear; // _paint.blendMode = BlendMode.src; // _paint.blendMode = BlendMode.dst; // _paint.blendMode = BlendMode.srcOver; // _paint.blendMode = BlendMode.dstOver; // _paint.blendMode = BlendMode.srcIn; // _paint.blendMode = BlendMode.dstIn; // _paint.blendMode = BlendMode.srcOut; // _paint.blendMode = BlendMode.dstOut; // _paint.blendMode = BlendMode.srcATop; // _paint.blendMode = BlendMode.dstATop; // _paint.blendMode = BlendMode.xor; // _paint.blendMode = BlendMode.plus; // _paint.blendMode = BlendMode.modulate; // _paint.blendMode = BlendMode.screen; // _paint.blendMode = BlendMode.overlay; // _paint.blendMode = BlendMode.darken; // _paint.blendMode = BlendMode.lighten; // _paint.blendMode = BlendMode.colorDodge; // _paint.blendMode = BlendMode.colorBurn; // _paint.blendMode = BlendMode.hardLight; // _paint.blendMode = BlendMode.softLight; // _paint.blendMode = BlendMode.difference; // _paint.blendMode = BlendMode.exclusion; // _paint.blendMode = BlendMode.multiply; // _paint.blendMode = BlendMode.hue; // _paint.blendMode = BlendMode.saturation; // _paint.blendMode = BlendMode.color; // _paint.blendMode = BlendMode.luminosity; _paint.color = Colors.blueAccent; canvas.drawCircle(Offset(250, 250), 100, _paint); Color = color.green; canvas.drawCircle(Offset(150, 250), 100, _paint); DrawImage (_src, Offset(0,400), _paint); // canvas. Restore (); } void translateToCenter(Canvas Canvas, Size Size) {Canvas. Translate (size.width / 2, size.height / 2); } @override bool shouldRepaint(CustomPainter oldDelegate) { return true; }}Copy the code

The rest of the effects are generated by modifying the comments in the blendMode section of the Settings. You can let go of any effect you want. I’m not going to post any more code.

clear

Official API description:

But the actual effect is this:This point, toss over for a long time, is still in doubt.

src

Official API description:

But the actual effect is this:

In doubt…

dst
  • Delete SRC and only draw DST.
  • Conceptually, SRC is discarded while DST remains the same.

The practical effect is:

srcOver
  • Draw SRC above DST.
  • This is the default value. It represents the most intuitive case, showing DST if SRC has a transparent region.

The practical effect is:

dstOver
  • Draw DST above SRC and display SRC if DST has a transparent area.
  • This is the opposite of srcOver.

The practical effect is:

srcIn
  • Displays DST, and displays the overlap between SRC and DST on DST.

The practical effect is:

dstIn

In practice, SRC does not display:

srcOut
  • The information that SRC and DST do not overlap is displayed, which is inconsistent with the official description.

The practical effect is:

dstOut
  • SrcOut is the exact opposite of srcOut

The practical effect is:

srcATop
  • SRC is synthesized to DST, DST is displayed, and overlap is displayed.

The practical effect is:

dstATop
  • This should be the opposite of srcATop, but it doesn’t work that way.

The practical effect is:

xor
  • Apply bitwise xOR operators to SRC and DST. This makes them transparent where they overlap.

The practical effect is:

plus
  • Adding the transparency of the overlaps increases the transparency of the overlaps.

The practical effect is:

modulate
  • Multiply the SRC and DST color components.
  • Times white, 1.0, it’s the same; Multiplied by black, 0.0, the result is black.
  • The color component is less than one, so if you multiply the overlap, the color component is smaller, so you make the image darker. For the parts that do not overlap, SRC is multiplied by transparency and becomes transparent, i.e., not shown.

In general, the overlap is darker, and the non-overlap SRC is not displayed. The practical effect is:

screen
  • Multiply the inverse of the SRC and DST components and find the inverse.
  • The inversion component means that a fully saturated channel (opaque white) is treated as a value of 0.0, while a value normally treated as 0.0 (black, transparent) is treated as a value of 1.0.
  • This is basically the same as modulation blending mode, but the color values are reversed before multiplication and the results are reversed back before rendering.
  • This can only produce the same or lighter color (multiplied by black, 1.0, the result remains the same; Multiply by white, 0.0, the result is white). Similarly, in the alpha channel, it can only produce more opaque colors.
  • This is similar to how two projectors display images on the same screen at the same time.

In short, the overlap becomes shallower and the non-overlap remains the same. The actual effect is:

overlay
  • Multiply the SRC and DST color components, then adjust them to support.
  • Specifically, if the DST color component is small, it is multiplied by the SRC value, while if the SRC value color component is small, the reciprocal of the SRC value is multiplied by the reciprocal of the DST value, and then the result is reversed.
  • The inversion component means that a fully saturated channel (opaque white) is treated as a value of 0.0, while a value normally treated as 0.0 (black, transparent) is treated as a value of 1.0.

In short, the non-overlap parts remain the same, and the overlap parts move toward DST. The practical effect is:

darken
  • Compose source and target images by selecting the lowest value from each color channel.

So in general, I’m going to use whichever color is darker in the overlap, and the overlap tends to be darker, and the non-overlap stays the same. The practical effect is:

lighten
  • Select the highest value from each color channel to synthesize SRC and DST.

So in general, the overlap is going to be lighter, the overlap is going to be lighter, the non-overlap is going to be the same. The practical effect is:

colorDodge
  • Divide DST by the reciprocal of SRC.
  • Reversing the color component means that a fully saturated channel (opaque white) is treated as a value of 0.0, while a value normally treated as 0.0 (black, transparent) is treated as a value of 1.0.
  • The overlap produces an effect

In short, the effect can not be summed up, ashamed. The practical effect is:

colorBurn
  • Divide the reciprocal of DST by SRC and find the reciprocal of the result.
  • Reversing the color component means that a fully saturated channel (opaque white) is treated as a value of 0.0, while a value normally treated as 0.0 (black, transparent) is treated as a value of 1.0.

In summary, the overlap is effective and the SRC opaque becomes transparent.

The practical effect is:

hardLight
  • Multiply the components of SRC and DST, and then adjust them to favor SRC.
  • Specifically, if the SRC value is small, it is multiplied by the DST value, and if the DST value is small, the reciprocal of the DST value is multiplied by the reciprocal of the SRC value, and then the result is reversed.
  • The inversion component means that a fully saturated channel (opaque white) is treated as a value of 0.0, while a value normally treated as 0.0 (black, transparent) is treated as a value of 1.0.

In short, the overlap is towards SRC. The practical effect is:

softLight
  • For a source value below 0.5, use colorDodge; For source values higher than 0.5, use colorBurn.

In short, the overlaps tend to favor DST. The practical effect is:

difference
  • Subtract the smaller value from the larger value for each channel.
  • [Fixed] Black has no effect Synthetic white reverses the color of other images.
  • The opacity of the output image is calculated in the same way as srcOver.
  • The effect is similar to exclusion but more severe.

The overlapping part has the effect, the color develops to the deeper overall, but the specific cannot summarize, ashamed. The practical effect is:

exclusion
  • Subtract twice the product of two images from the sum of the two images.
  • [Fixed] Black has no effect Synthetic white reverses the color of other images.
  • The opacity of the output image is calculated in the same way as srcOver.
  • The effect is similar to Difference, but softer.

The overlapping part has the effect, the color develops to the lighter overall, but the specific cannot summarize, ashamed. The practical effect is:

multiply
  • Multiply the components of SRC and the target image, including the alpha channel.
  • This can only produce the same or darker color (multiply by white, 1.0, the result remains the same; Multiplied by black, 0.0, the result is black).
  • Since alpha channels are also multiplied, fully transparent pixels in one image (opacity 0.0) result in fully transparent pixels in the output. This is similar to dstIn, but the colors are combined.
  • For variants that multiply colors but not alpha channels, consider Modulate.

Anyway, the overlap, darker and more transparent actually looks like this:

hue
  • Gets the SRC hue, as well as the saturation and brightness of the target image.
  • The effect is to color the target image with SRC.
  • The completely transparent region in SRC gets its hue from the target image.

The practical effect is:

saturation
  • Get SRC saturation, as well as DST hue and brightness.
  • The opacity of the output image is calculated in the same way as srcOver. Saturation is obtained from DST in areas that are completely transparent in SRC.

The practical effect is:

color
  • Get the hue and saturation of SRC, and the brightness of DST.
  • The effect is to color DST with SRC.
  • The opacity of the output image is calculated in the same way as srcOver. The completely transparent areas in SRC get their hue and saturation from DST.

The practical effect is:

luminosity
  • Gets the brightness of SRC, and the hue and saturation of DST.
  • The opacity of the output image is calculated in the same way as srcOver. Regions that are completely transparent in SRC get their brightness from DST.

The practical effect is:

The above is only personal test results, if there is any error, look forward to correct!

over-