kwimage.im_alphablend module¶
Numpy implementation of alpha blending based on information in [SO25182421] and [WikiAlphaBlend].
For more types of blending see [PypiBlendModes] and [WikiAlphaBlend].
References
- kwimage.im_alphablend.overlay_alpha_layers(layers, keepalpha=True, dtype=<class 'numpy.float32'>)[source]¶
Stacks a sequences of layers on top of one another. The first item is the topmost layer and the last item is the bottommost layer.
- Parameters:
layers (Sequence[ndarray]) – stack of images
keepalpha (bool) – if False, the alpha channel is removed after blending
dtype (np.dtype) – format for blending computation (defaults to float32)
- Returns:
raster: the blended images
- Return type:
ndarray
Example
>>> import kwimage >>> keys = ['astro', 'carl', 'stars'] >>> layers = [kwimage.grab_test_image(k, dsize=(100, 100)) for k in keys] >>> layers = [kwimage.ensure_alpha_channel(g, alpha=.5) for g in layers] >>> stacked = kwimage.overlay_alpha_layers(layers) >>> # xdoctest: +REQUIRES(--show) >>> import kwplot >>> kwplot.autompl() >>> kwplot.imshow(stacked) >>> kwplot.show_if_requested()
- kwimage.im_alphablend.overlay_alpha_images(img1, img2, keepalpha=True, dtype=<class 'numpy.float32'>, impl='inplace')[source]¶
Places img1 on top of img2 respecting alpha channels. Works like the Photoshop layers with opacity.
- Parameters:
img1 (ndarray) – top image to overlay over img2
img2 (ndarray) – base image to superimpose on
keepalpha (bool) – if False, the alpha channel is removed after blending
dtype (np.dtype) – format for blending computation (defaults to float32)
impl (str) – code specifying the backend implementation
- Returns:
raster: the blended images
- Return type:
ndarray
Todo
[ ] Make fast C++ version of this function
Example
>>> import kwimage >>> img1 = kwimage.grab_test_image('astro', dsize=(100, 100)) >>> img2 = kwimage.grab_test_image('carl', dsize=(100, 100)) >>> img1 = kwimage.ensure_alpha_channel(img1, alpha=.5) >>> img3 = kwimage.overlay_alpha_images(img1, img2) >>> # xdoctest: +REQUIRES(--show) >>> import kwplot >>> kwplot.autompl() >>> kwplot.imshow(img3) >>> kwplot.show_if_requested()
- kwimage.im_alphablend._alpha_blend_simple(rgb1, alpha1, rgb2, alpha2)[source]¶
Core alpha blending algorithm
- SeeAlso:
_alpha_blend_inplace - alternative implementation
- kwimage.im_alphablend._alpha_blend_inplace(rgb1, alpha1, rgb2, alpha2)[source]¶
Uglier but faster(? maybe not) version of the core alpha blending algorithm using preallocation and in-place computation where possible.
- SeeAlso:
_alpha_blend_simple - alternative implementation
Example
>>> rng = np.random.RandomState(0) >>> rgb1, rgb2 = rng.rand(10, 10, 3), rng.rand(10, 10, 3) >>> alpha1, alpha2 = rng.rand(10, 10), rng.rand(10, 10) >>> f1, f2 = _alpha_blend_inplace(rgb1, alpha1, rgb2, alpha2) >>> s1, s2 = _alpha_blend_simple(rgb1, alpha1, rgb2, alpha2) >>> assert np.all(f1 == s1) and np.all(f2 == s2) >>> alpha1, alpha2 = np.zeros((10, 10)), np.zeros((10, 10)) >>> f1, f2 = _alpha_blend_inplace(rgb1, alpha1, rgb2, alpha2) >>> s1, s2 = _alpha_blend_simple(rgb1, alpha1, rgb2, alpha2) >>> assert np.all(f1 == s1) and np.all(f2 == s2)
- kwimage.im_alphablend._alpha_blend_numexpr1(rgb1, alpha1, rgb2, alpha2)[source]¶
Alternative. Not well optimized
- kwimage.im_alphablend._alpha_blend_numexpr2(rgb1, alpha1, rgb2, alpha2)[source]¶
Alternative. Not well optimized
- kwimage.im_alphablend.ensure_alpha_channel(img, alpha=1.0, dtype=<class 'numpy.float32'>, copy=False)[source]¶
Returns the input image with 4 channels.
- Parameters:
img (ndarray) – an image with shape [H, W], [H, W, 1], [H, W, 3], or [H, W, 4].
alpha (float | ndarray) – default scalar value for missing alpha channel, or an ndarray with the same height / width to use explicitly.
dtype (type) – The final output dtype. Should be numpy.float32 or numpy.float64.
copy (bool) – always copy if True, else copy if needed.
- Returns:
an image with specified dtype with shape [H, W, 4].
- Return type:
ndarray
- Raises:
ValueError - if the input image does not have 1, 3, or 4 input channels – or if the image cannot be converted into a float01 representation
Example
>>> # Demo with a scalar default alpha value >>> import kwimage >>> data0 = np.zeros((5, 5)) >>> data1 = np.zeros((5, 5, 1)) >>> data2 = np.zeros((5, 5, 3)) >>> data3 = np.zeros((5, 5, 4)) >>> ensured0 = kwimage.ensure_alpha_channel(data0, alpha=0.5) >>> ensured1 = kwimage.ensure_alpha_channel(data1, alpha=0.5) >>> ensured2 = kwimage.ensure_alpha_channel(data2, alpha=0.5) >>> ensured3 = kwimage.ensure_alpha_channel(data3, alpha=0.5) >>> assert np.all(ensured0[..., 3] == 0.5), 'should have been populated' >>> assert np.all(ensured1[..., 3] == 0.5), 'should have been populated' >>> assert np.all(ensured2[..., 3] == 0.5), 'should have been populated' >>> assert np.all(ensured3[..., 3] == 0.0), 'last image already had alpha'
Example
>>> import kwimage >>> # Demo with a explicit alpha channel >>> alpha = np.random.rand(5, 5) >>> data0 = np.zeros((5, 5)) >>> data1 = np.zeros((5, 5, 1)) >>> data2 = np.zeros((5, 5, 3)) >>> data3 = np.zeros((5, 5, 4)) >>> ensured0 = kwimage.ensure_alpha_channel(data0, alpha=alpha) >>> ensured1 = kwimage.ensure_alpha_channel(data1, alpha=alpha) >>> ensured2 = kwimage.ensure_alpha_channel(data2, alpha=alpha) >>> ensured3 = kwimage.ensure_alpha_channel(data3, alpha=alpha) >>> assert np.all(ensured0[..., 3] == alpha), 'should have been populated' >>> assert np.all(ensured1[..., 3] == alpha), 'should have been populated' >>> assert np.all(ensured2[..., 3] == alpha), 'should have been populated' >>> assert np.all(ensured3[..., 3] == 0.0), 'last image already had alpha'