:py:mod:`kwimage.im_alphablend` =============================== .. py:module:: kwimage.im_alphablend Module Contents --------------- Functions ~~~~~~~~~ .. autoapisummary:: kwimage.im_alphablend.overlay_alpha_layers kwimage.im_alphablend.overlay_alpha_images kwimage.im_alphablend._prep_rgb_alpha kwimage.im_alphablend._alpha_blend_simple kwimage.im_alphablend._alpha_blend_inplace kwimage.im_alphablend._alpha_blend_numexpr1 kwimage.im_alphablend._alpha_blend_numexpr2 kwimage.im_alphablend.ensure_alpha_channel .. py:function:: overlay_alpha_layers(layers, keepalpha=True, dtype=np.float32) 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 :rtype: ndarray .. rubric:: References http://stackoverflow.com/questions/25182421/overlay-numpy-alpha https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending .. rubric:: 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 = overlay_alpha_layers(layers) >>> # xdoctest: +REQUIRES(--show) >>> import kwplot >>> kwplot.autompl() >>> kwplot.imshow(stacked) >>> kwplot.show_if_requested() .. py:function:: overlay_alpha_images(img1, img2, keepalpha=True, dtype=np.float32, impl='inplace') 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, default=inplace*) -- code specifying the backend implementation :returns: raster: the blended images :rtype: ndarray .. todo:: - [ ] Make fast C++ version of this function .. rubric:: References http://stackoverflow.com/questions/25182421/overlay-numpy-alpha https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending .. rubric:: 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 = overlay_alpha_images(img1, img2) >>> # xdoctest: +REQUIRES(--show) >>> import kwplot >>> kwplot.autompl() >>> kwplot.imshow(img3) >>> kwplot.show_if_requested() .. py:function:: _prep_rgb_alpha(img, dtype=np.float32) .. py:function:: _alpha_blend_simple(rgb1, alpha1, rgb2, alpha2) Core alpha blending algorithm SeeAlso: _alpha_blend_inplace - alternative implementation .. py:function:: _alpha_blend_inplace(rgb1, alpha1, rgb2, alpha2) 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 .. rubric:: 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) .. py:function:: _alpha_blend_numexpr1(rgb1, alpha1, rgb2, alpha2) Alternative. Not well optimized .. py:function:: _alpha_blend_numexpr2(rgb1, alpha1, rgb2, alpha2) Alternative. Not well optimized .. py:function:: ensure_alpha_channel(img, alpha=1.0, dtype=np.float32, copy=False) 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, default=1.0*) -- default value for missing alpha channel * **dtype** (*type, default=np.float32*) -- a numpy floating type * **copy** (*bool, default=False*) -- always copy if True, else copy if needed. :returns: an image with specified dtype with shape [H, W, 4]. :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