Python implementation of CSS3 blend mode and talk of color space

What is CSS3 blend mode?

It is a "blend mode (drawing mode)" function installed in image editing tools such as Photoshop, but it is also implemented in CSS3 with a property called mix-blend-mode. Since it is CSS3, it is naturally necessary to unify the appearance in each browser (other than IE), so the calculation formula for each blend mode is listed in the W3C specifications.

Compositing and Blending Compositing and Blending Japanese translation

In addition, it seems that Adobe employees are also involved in the formulation, and it seems that the same formula as the blend mode of Adobe products such as Photoshop is used.

Surprisingly difficult "Non-separable blend"

As you read the W3C specifications, the blend modes are divided into two categories: "Separable blend" and "Non-separable blend". "Non-separable blend" is a blend that considers all color component combinations without treating each component individually.

"Separable blend" uses simple formulas such as screen and ʻoverlay, so there is no problem. There are four problems: hue, saturation, color, and luminosity`, which are classified as "Non-separable blend".

For example, the hue mode is a mode in which the hue (Hue) of the source image is applied while maintaining the brightness of the background image. Let's combine the two images below in hue mode.

backdrop.png ducky.png

The composition result is as follows.

hue.png

It's not a simple story, "Because I'm transplanting hue, I convert it to HSV color space and transplant H component ...". While porting the hue, the brightness of the original image must be maintained, that is, when the composite result is monochromed, it must be as follows.

hue.png <iclass="fafa-arrow-right"aria-hidden="true">hue_mono.png

The duck has completely disappeared.

The story of Value, Lightness, and Luminance

There are two commonly used color spaces that deal with hue (Hue): the HSV color space and the HSL color space. The HSV color space is composed of Hue, Saturation, and Value.

HSV Color Space-Wikipedia

The HSL color space is composed of three parts: hue, saturation, and lightness.

HSL Color Space-Wikipedia

Wikipedia describes it as Luminance in the HSL color space, which is different from Luminance. Be aware that the word confusion here can be found on various pages.

The general formula for converting from RGB to Luminance is:

r * 0.298912 + g * 0.586611 + b * 0.114478

The conversion formula for HSL to L (Lightness) is as follows.

(MAX(r, g, b) - MIN(r, g, b)) / 2

Clearly, it's completely different. The translation of Lightness varies depending on the material such as "brightness" and "brightness", so it is important not to be confused.

Interpretation of SetSat

A pseudo-code function called SetSat is described in the W3C formula.

SetSat(C, s)
    if(Cmax > Cmin)
        Cmid = (((Cmid - Cmin) x s) / (Cmax - Cmin))
        Cmax = s
    else
        Cmid = Cmax = 0
    Cmin = 0
    return C;

When I first saw this pseudocode, I didn't understand what it meant. Cmin is the minimum value of the RGB components, Cmax is the maximum value, and Cmid is the median value.

For example, if C = RGB (0,8, 0.6, 0.3), Cmin is B element (0.3), Cmax is R element (0.8), and Cmid is G element (0.6). I will. The calculation formula is as follows.

G = (((G - B) x s) / (R - B))
R = s
B = 0.0

It means that. By the way, it doesn't describe what happens when there are two Cmin and Cmax like RGB (0.1, 0.1, 0.5) and RGB (0.5, 0.5, 0.1). I don't know what the correct answer will be, but it seems that any value will do as long as the following conditions are met.

max(Cred, Cgreen, Cblue) - min(Cred, Cgreen, Cblue) == s

Implementation in Python (pillow)

Now that we know the formula, we'll implement it in the Python image library pillow. Pillow is essentially a Python standard image library. It does not have advanced functions like OpenCV, but it can convert data to various libraries and features compact and high-speed image processing.

The blend mode implementation uses the ʻImageMath` module, as described in the PIL / Pillow cheat sheet (http://qiita.com/pashango2/items/145d858eff3c505c100a#_reference-35595a161656dd8d793c).

Let's implement hard-light as an example.

from PIL import ImageMath


def _hard_light(a, b):
    _cl = 2 * a * b / 255
    _ch = 2.0 * (a + b - a * b / 255.0) - 255.0
    return _cl * (b < 128) + _ch * (b >= 128)

bands = []
for cb, cs in zip(backdrop.split(), source.split()):
    t = ImageMath.eval(
        "func(float(a), float(b))",
        func=_hard_light,
        a=cb, b=cs
    ).convert("L")
    bands += [t]
    
Image.merge("RGB", bands)

The ʻImageMath` module is useful because it allows you to calculate elements like numbers. For simple processing like "Separable blend", you can implement it like this.

The problem is "Non-separable blend", which is quite difficult due to the unexpectedly large amount of calculation and tricky processing. Regarding the implementation, I will publish the code later, so if you are interested, I will implement it by making full use of the private functions of the ʻImageMath` module. If you want to port in another language, I think you will use GLSL etc., I hope it will be helpful.

"Image4Layer" module

We have packaged these processes under the module name "Image4Layer". I often use ʻoverlay` composition in image processing systems, so I think there are quite a few things to use.

https://github.com/pashango2/Image4Layer

Installation is easy with pip, pillow (PIL) must be pre-installed to run.

$pip install image4layer

It's easy to use, it's an example of compositing in color-dodge mode.

from PIL import Image
from image4layer import Image4Layer

source = Image.open("ducky.png ")
backdrop = Image.open("backdrop.png ")

Image4Layer.color_dodge(backdrop, source)

color_dodge.png

It's easy, below is a list of supported blend modes.

Blend mode image
Image4Layer.normal normal.png
Image4Layer.multiply multiply.png
Image4Layer.screen screen.png
Image4Layer.overlay overlay.png
Image4Layer.darken darken.png
Image4Layer.lighten lighten.png
Image4Layer.color_dodge color_dodge.png
Image4Layer.color_burn color_burn.png
Image4Layer.hard_light hard_light.png
Image4Layer.soft_light soft_light.png
Image4Layer.difference diff.png
Image4Layer.exclusion exc.png
Image4Layer.hue hue.png
Image4Layer.saturation sat.png
Image4Layer.color color.png
Image4Layer.luminosity lum.png

Although not in CSS3, I also implemented the blend mode that Photoshop has.

Blend mode image
Image4Layer.vivid_light vivid.png
Image4Layer.pin_light pin.png
Image4Layer.linear_dodge linear.png
Image4Layer.subtract sub.png

The license is MIT, so you can use it for free for commercial or personal use.

Postscript

Version 0.4 did not work with Python 2 and there was a bug in the operation between RGBA, which has been fixed in 0.43.

Afterword

Compositing and Blending Japanese translation has the expected drawing and the actual browser display, but when I access it with Chrome It will be as follows.

範囲を選択_040.png

that···? Isn't the color quite different? It seems that the colors of the display around here will differ considerably depending on each browser.

Postscript

The color seems to be different depending on the version of Chrome, my environment is Ubuntu environment, and it seems that there is a bug in the composition of the alpha value set in backdrop.png.

By the way, the display result of Image4Lyaer is almost the same as the result of Chrome, I think that it has almost the same implementation. If there is any information, I will write it as needed.

Recommended Posts

Python implementation of CSS3 blend mode and talk of color space
Implementation of particle filters in Python and application to state space models
Implementation of TRIE tree with Python and LOUDS
Explanation of edit distance and implementation in Python
Overview of generalized linear models and implementation in Python
Explanation and implementation of SocialFoceModel
Detect objects of a specific color and size with Python
Python implementation of particle filters
Maxout description and implementation (Python)
Implementation of quicksort in Python
Handling of HSV color space lower and upper in OpenCV
Source installation and installation of Python
Crawling with Python and Twitter API 2-Implementation of user search function
[Python] I thoroughly explained the theory and implementation of logistic regression
[Python] I thoroughly explained the theory and implementation of decision trees
[Python] Implementation of Nelder–Mead method and saving of GIF images by matplotlib
Environment construction of python and opencv
The story of Python and the story of NaN
Explanation and implementation of PRML Chapter 4
Introduction and Implementation of JoCoR-Loss (CVPR2020)
Explanation and implementation of ESIM algorithm
Installation of SciPy and matplotlib (Python)
Introduction and implementation of activation function
Sorting algorithm and implementation in Python
Python implementation of self-organizing particle filters
Implementation of life game in Python
Explanation and implementation of simple perceptron
This and that of python properties
Implementation of desktop notifications using Python
Python implementation of non-recursive Segment Tree
Implementation of Light CNN (Python Keras)
Implementation of original sorting in Python
Implementation of Dijkstra's algorithm with python
Coexistence of Python2 and 3 with CircleCI (1.0)
Summary of Python indexes and slices
Reputation of Python books and reference books
Change the saturation and brightness of color specifications like # ff000 in python 2.5
Derivation of multivariate t distribution and implementation of random number generation by python
Open an Excel file in Python and color the map of Japan
[Control engineering] Calculation of transfer functions and state space models by Python
Installation of Visual studio code and installation of python
Implementation and experiment of convex clustering method
Implementation module "deque" in queue and Python
Extraction of tweet.js (json.loads and eval) (Python)
Python data structure and internal implementation ~ List ~
Connect a lot of Python or and and
Explanation and implementation of Decomposable Attention algorithm
Easy introduction of python3 series and OpenCV3
[Python] Various combinations of strings and values
Idempotent automation of Python and PyPI setup
Full understanding of Python threading and multiprocessing
Non-recursive implementation of extended Euclidean algorithm (Python)
Python implementation of continuous hidden Markov model
Project Euler # 1 "Multiples of 3 and 5" in Python
Transfer function / state space model of RLC series circuit and simulation by Python
[Python] Comparison of Principal Component Analysis Theory and Implementation by Python (PCA, Kernel PCA, 2DPCA)
Deep Learning from scratch The theory and implementation of deep learning learned with Python Chapter 3
Build a python environment to learn the theory and implementation of deep learning
[Python] I thoroughly explained the theory and implementation of support vector machine (SVM)