blends

Blending operations to use when combining two sets of image data.

Many of these are taken from:

Basic Usage: Blends

The blending operation functions (blends) are used to blend two sets of image data together. Using a blending operation (a “blend”) works like any other function.

Usage:

>>> import numpy as np
>>> a = np.array([[[0., .25, .5, .75, 1.], [0., .25, .5, .75, 1.]]])
>>> b = np.array([[[1., 75, .5, .25, 0.], [1., 75, .5, .25, 0.]]])
>>> darker(a, b)
array([[[0.  , 0.25, 0.5 , 0.25, 0.  ],
        [0.  , 0.25, 0.5 , 0.25, 0.  ]]])

While the functions themselves are fairly simple, they are given some extra functionality by decorators. Ultimately the true Blending Operation protocol is:

param a:

The image data from the existing image.

param b:

The image data from the blending image.

param colorize:

(Optional). Whether to ensure the two images have the same number of color channels.

param fade:

(Optional.) (From @can_fade.) How much the blend should impact the final output. This is a percentage, so the range of valid values are 0 <= x <= 1.

param mask:

(Optional.) (From @mcan_mask.) An array of data used to mask the blending operation. This is also a percentage, so a value of one in the mask means that pixel is fully affected by the operation. A value of zero means the pixel is not affected by the operation.

return:

A numpy.ndarray object.

rtype:

numpy.ndarray

Colorize, Array Shape, and Color Channels

The blends themselves don’t care about the dimensionality of the given arrays. It just needs the two arrays to have the same shape by the time it does the blend. While this was originally written for image data, to the algorithms themselves, it’s all just floating-point math.

However, there is one case where a bias towards image data shows up:

  • You pass two arrays with differing shapes,

  • The size of their last dimension is different,

  • One of the two arrays has a last dimension with size three.

To perform the blending algorithm, the two arrays must be the same shape. In most cases, differences between the two shapes will be handled through the pjimg.blends.will_match_size() decorator, which adds zeros to the smaller array to make their sizes match. However, in the case described above, something different happens.

Since color image data often has a last dimension size of three, representing color channels, the case above is intercepted by the img.blender.common.will_colorize() decorator. That decorator assumes the array that doesn’t have a last dimension size of three is single channel image data (“grayscale”) and will add a new last dimension of size three. The values will be the original single value repeated three times. To demonstrate:

>>> from pjimg.blends import will_colorize
>>> a = np.array([
...     [1.0, 0.5, 0.0, ],
...     [0.5, 0.0, 0.5, ],
...     [0.0, 0.5, 1.0, ],
... ])
>>> b = np.array([
...     [[0, 0, 0], [0, 0, 0], [0, 0, 0], ],
...     [[0, 0, 0], [0, 0, 0], [0, 0, 0], ],
...     [[0, 0, 0], [0, 0, 0], [0, 0, 0], ],
... ])
>>>
>>> @will_colorize
... def spam(a, b):
...     return a
...
>>> a_ = spam(a, b)
>>> a_
array([[[1. , 1. , 1. ],
        [0.5, 0.5, 0.5],
        [0. , 0. , 0. ]],

       [[0.5, 0.5, 0.5],
        [0. , 0. , 0. ],
        [0.5, 0.5, 0.5]],

       [[0. , 0. , 0. ],
        [0.5, 0.5, 0.5],
        [1. , 1. , 1. ]]])
>>> a.shape
(3, 3)
>>> a_.shape
(3, 3, 3)

The value returned by `spam()` in the demonstration has an extra dimension of size three added, and the values are three copies of the values in the original `a``.

This can be turned off by passing `False` to the `colorize` parameter of the blend.

Registration

All blending operations are registered in dict pjimg.eases.blends for convenience, but they can also be called directly.

Blend Operations

The examples in the following blends will show the result when a simple horizontal gradient:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
The simple horizontal gradient `a`.

The simple horizontal gradient a.

is blended with a simple vertical gradient:

>>> b = Gradient('v').fill((1, 720, 1280))
The simple horizontal gradient `b`.

The simple horizontal gradient b.

Replacement Blends

pjimg.blends.replace(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Simple replacement filter. Can double as an opacity filter if passed can_fade amount, but otherwise this will just replace the values in a with the values in b.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = replace(a, b)
The result of :func:`replace`.

The result of replace().

Darker/Burn Blends

pjimg.blends.darker(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Replaces values in the existing image with values from the blending image when the value in the blending image is darker.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = darker(a, b)
The result of :func:`darker`.

The result of darker().

pjimg.blends.multiply(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Multiplies the values of the two images, leading to darker values. This is useful for shadows and similar situations.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = multiply(a, b)
The result of :func:`multiply`.

The result of multiply().

pjimg.blends.color_burn(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Similar to multiply, but is darker and produces higher contrast.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = color_burn(a, b)
The result of :func:`color_burn`.

The result of color_burn().

pjimg.blends.linear_burn(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Similar to multiply, but is darker, produces less saturated colors than color burn, and produces more contrast in the shadows.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = linear_burn(a, b)
The result of :func:`linear_burn`.

The result of linear_burn().

Lighter/Dodge Blends

pjimg.blends.lighter(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Replaces values in the existing image with values from the blending image when the value in the blending image is lighter.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = lighter(a, b)
The result of :func:`lighter`.

The result of lighter().

pjimg.blends.screen(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Performs an inverse multiplication on the colors from the two images then inverse the colors again. This leads to overall brighter colors and is the opposite of multiply.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = screen(a, b)
The result of :func:`screen`.

The result of screen().

pjimg.blends.color_dodge(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Similar to screen, but brighter and decreases the contrast.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = color_dodge(a, b)
The result of :func:`color_dodge`.

The result of color_dodge().

pjimg.blends.linear_dodge(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Similar to screen but produces stronger results.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = linear_dodge(a, b)
The result of :func:`linear_dodge`.

The result of linear_dodge().

Inversion Blends

pjimg.blends.difference(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Takes the absolute value of the difference of the two values. This is often useful in creating complex patterns or when aligning two images.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = difference(a, b)
The result of :func:`difference`.

The result of difference().

pjimg.blends.exclusion(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Similar to difference, with the result tending to gray rather than black.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = exclusion(a, b)
The result of :func:`exclusion`.

The result of exclusion().

Contrast Blends

pjimg.blends.hard_light(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Similar to the blending image being a harsh light shining on the existing image.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = hard_light(a, b)
The result of :func:`hard_light`.

The result of hard_light().

pjimg.blends.hard_mix(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Increases the saturation and contrast. It’s best used with masks and can_fade.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = hard_mix(a, b)
The result of :func:`hard_mix`.

The result of hard_mix().

pjimg.blends.linear_light(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Combines linear dodge and linear burn.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = linear_light(a, b)
The result of :func:`linear_light`.

The result of linear_light().

pjimg.blends.overlay(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Combines screen and multiply blends.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = overlay(a, b)
The result of :func:`overlay`.

The result of overlay().

pjimg.blends.pin_light(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Combines lighten and darken blends.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = pin_light(a, b)
The result of :func:`pin_light`.

The result of pin_light().

pjimg.blends.soft_light(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Similar to overlay, but biases towards the blending value rather than the existing value.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = soft_light(a, b)
The result of :func:`soft_light`.

The result of soft_light().

pjimg.blends.vivid_light(a: ndarray[tuple[int, ...], dtype[float64]], b: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]][source]

Good for color grading when faded.

Parameters:
  • a – The existing values. This is like the bottom layer in a photo editing tool.

  • b – The values to blend. This is like the top layer in a photo editing tool.

  • colorize – (Optional). Whether to ensure the two images have the same number of color channels.

  • fade – (Optional.) The amount the blended values should affect the existing values. This is a float between zero and one, where zero is no effect and one is full effect. See blendser.common.can_fade() for more details.

  • mask – (Optional.) An image mask that is used to determine the effect the blend should have on the existing values. This is a numpy.ndarray of floats between zero and one, where zero is no effect and one is full effect. See blendser.common.can_mask() for details.

Returns:

An numpy.ndarray that contains the values of the blended arrays.

Return type:

numpy.ndarray

Usage:

>>> from pjimg.sources import Gradient
>>> a = Gradient('h').fill((1, 720, 1280))
>>> b = Gradient('v').fill((1, 720, 1280))
>>> img = vivid_light(a, b)
The result of :func:`vivid_light`.

The result of vivid_light().

Decorators

Common decorators used by pjimg.blends.

pjimg.blends.can_fade(fn: Callable[[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]], ndarray[tuple[int, ...], dtype[float64]]]) Callable[[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]], ndarray[tuple[int, ...], dtype[float64]]][source]

Adjust how much the blend affects the base array.

Parameters:

fn – The blend function to wrap.

Returns:

The wrapped blend function.

Return type:

function

pjimg.blends.can_mask(fn: Callable[[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]], ndarray[tuple[int, ...], dtype[float64]]]) Callable[[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]], ndarray[tuple[int, ...], dtype[float64]]][source]

Apply a blending mask to the image.

Parameters:

fn – The blend function to wrap.

Returns:

The wrapped blend function.

Return type:

function

pjimg.blends.register(registry: dict[str, Callable[[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]], ndarray[tuple[int, ...], dtype[float64]]]]) Callable[[Callable[[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]], ndarray[tuple[int, ...], dtype[float64]]]], Callable[[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]], ndarray[tuple[int, ...], dtype[float64]]]][source]

Registers the decorated function under the function’s name in the given registry dictionary.

Parameters:

registry – The registry to register the given function in.

Returns:

The registration function pointed to the given registry.

Return type:

function

pjimg.blends.will_clip(fn: Callable[[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]], ndarray[tuple[int, ...], dtype[float64]]]) Callable[[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]], ndarray[tuple[int, ...], dtype[float64]]][source]

Blends that use division or unbounded addition or subtraction can overflow the scale of the image. This will keep the image in scale by clipping the values below zero to zero and the values above one to one.

Parameters:

fn – The blend function to wrap.

Returns:

The wrapped blend function.

Return type:

function

pjimg.blends.will_colorize(fn: Callable[[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]], ndarray[tuple[int, ...], dtype[float64]]]) Callable[[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]], ndarray[tuple[int, ...], dtype[float64]]][source]

Ensure the images have the same number of color channels.

Parameters:

fn – The blend function to wrap.

Returns:

The wrapped blend function.

Return type:

function

pjimg.blends.will_match_size(fn: Callable[[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]], ndarray[tuple[int, ...], dtype[float64]]]) Callable[[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]], ndarray[tuple[int, ...], dtype[float64]]][source]

If the given images are different sizes, increase the size of the smaller image to match the larger image. Since this affects the size of the images, this will need to go before any decorators that use the original images to affect the resulting image.

Parameters:

fn – The blend function to wrap.

Returns:

The wrapped blend function.

Return type:

function