normal_grain_merge
This implements a combined version of the blend modes normal and grain merge. Grain merge is performed on s and t with the result normal-merged with b. Subscripts indicate channels, with alpha (α) channels broadcast to three channels.
$$ (((\mathrm{t_{rgb}} + \mathrm{s_{rgb}} - 0.5) * \mathrm{t_\alpha} + \mathrm{t_{rgb}} * (1 - \mathrm{t_\alpha})) * (1 - 0.3) + \mathrm{s_{rgb}} * 0.3) * \mathrm{t_\alpha} + \mathrm{b_{rgb}} * (1 - \mathrm{t_\alpha}) $$
Installation
pip install normal-grain-merge
Usage
import numpy as np
from normal_grain_merge import normal_grain_merge, KernelKind
# Example arrays
base = np.zeros((100, 100, 3), dtype=np.uint8)
texture = np.zeros((100, 100, 3), dtype=np.uint8)
skin = np.zeros((100, 100, 4), dtype=np.uint8)
im_alpha = np.zeros((100, 100), dtype=np.uint8)
result_scalar = normal_grain_merge(base, texture, skin, im_alpha, KernelKind.KERNEL_SCALAR.value)
print(result_scalar.shape, result_scalar.dtype)
There are three kernels implemented in this module as defined in KernelKind.
KERNEL_AUTO: Automatically chooses the kernel, preferring AVX2KERNEL_SCALAR: Portable scalar implementation.KERNEL_SSE42: SSE4.2 intrinsics kernel. Likely better on AMD CPUs.KERNEL_AVX2: AVX2 intrinsics kernel. Likely better on Intel CPUs.
Parameters
All input matrices should have the same height and width.
base
RGB or RGBA, dropping the alpha channel if it exists. The base image for application.
texture
RGB or RGBA, applying the alpha if it exists. This is the texture to be applied.
skin
RGBA, the segmented portion of base to texture. The "skin" of the object the texture is to be applied to.
im_alpha
The alpha of parameter skin.
This is mostly a holdover from the Python implementation to deal with NumPy.
kernel
One of KernelKind.
Performance
The entire reason for me writing this was NumPy being slow when this operation is in the hot path. So, I decided to write a SIMD version that does the type casting outside NumPy with only the intermediate values being in FP32.
How much of a speedup is this? All numbers are from a Ryzen 7 4800H running Ubuntu 24.04 and Python 3.12.3.
| Method/Kernel | Average Iteration Time (RGB) | Average Iteration Time (RGBA) |
|---|---|---|
| C scalar kernel | 0.016109s | 0.016679s |
| C SSE4.2 kernel | 0.002446s | 0.002478s |
| C AVX2 kernel | 0.002336s | 0.002520s |
| NumPy version | 0.160623s | 0.258044s |
| Old NumPy version | 0.248160s | 0.232046s |
| Method Comparison | Speedup (RGB) | Speedup (RGBA) |
|---|---|---|
| NumPy -> scalar | 89.9709% | 93.5363% |
| NumPy -> SSE4.2 | 98.4769% | 99.0397% |
| NumPy -> AVX2 | 98.5454% | 99.0235% |
| Old np -> SSE4.2 | 99.0142% | 98.9321% |
| Old np -> AVX2 | 99.0585% | 98.9141% |
| C scalar -> SSE4.2 | 84.8135% | 85.1437% |
| C scalar -> AVX2 | 85.4964% | 84.8923% |
Metadata
Release files for normal-grain-merge 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| normal_grain_merge-0.1.3.tar.gz | 16.5 kB | Details |
Built distributions (wheels)
Total release size: 1.7 MB
Release files / normal_grain_merge-0.1.3.tar.gz
| Download URL | normal_grain_merge-0.1.3.tar.gz |
|---|---|
| Size | 16.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
15022ed056fb470dc1ab4f9261f403453b2321df215ebcddb7acf53e8d57d25c
|
|
BLAKE2b-256 checksum How to use checksums |
14a9075c69c61e0fdd3a18deec81507fa9fb9a6f92c00e0869de1c32619a94b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp313-cp313-win_amd64.whl
| Download URL | normal_grain_merge-0.1.3-cp313-cp313-win_amd64.whl |
|---|---|
| Size | 26.9 kB |
| Tags | CPython 3.13 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
993a05b37c61823c895fea481864c121eb713b8e5860b3969312683670bd1276
|
|
BLAKE2b-256 checksum How to use checksums |
48c886e9419fb47fa1fec8e0851cc0221e53c6dcf9a380abc9dddf4d6fd31bb8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp313-cp313-musllinux_1_2_x86_64.whl
| Download URL | normal_grain_merge-0.1.3-cp313-cp313-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 125.5 kB |
| Tags | CPython 3.13 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
6b5170d430a1327c3545eba567ff831ba7640534a274d3093863c87337d7e8f9
|
|
BLAKE2b-256 checksum How to use checksums |
dc5555283783b56c42697964d2173cd40620e0d62e2c7660e98dd3870484c4df
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | normal_grain_merge-0.1.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 130.1 kB |
| Tags | CPython 3.13 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
f69bf6cb694ebd3a49012c4a8dcb048a0ccc2a5caae90416f12f856a03838ba9
|
|
BLAKE2b-256 checksum How to use checksums |
9152198ba412914cbdbb7330d10c6254a9513d45e3d9bd7326f53c82e56ff1a1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp312-cp312-win_amd64.whl
| Download URL | normal_grain_merge-0.1.3-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 26.9 kB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
b1eb0f8b2eb81f0ac74794f7358f6b8ad363ff79efec8739c498182fb02a7edb
|
|
BLAKE2b-256 checksum How to use checksums |
31634ab082079bcd5f1b74e53b3f2d72605c63e7e96b2b9ba51c848703763617
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp312-cp312-musllinux_1_2_x86_64.whl
| Download URL | normal_grain_merge-0.1.3-cp312-cp312-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 125.4 kB |
| Tags | CPython 3.12 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
2822968143cfcffa9f30f7cacdfe74ecb9efc8bbaf6de4676f3203410e30514d
|
|
BLAKE2b-256 checksum How to use checksums |
2e5c64e02137bc1650cd7f5ccd60c2aaa36c3633cbead74c27175b3475e4c8fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | normal_grain_merge-0.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 130.1 kB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
25b352593cd4857cc5a0207330376fc39e8c3960b2d651ff992ae792f0cd8d98
|
|
BLAKE2b-256 checksum How to use checksums |
6d3a8280faba900bc53268ee371ba92ac6611be7cf4e3c7c654fd7e812ad5d08
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp311-cp311-win_amd64.whl
| Download URL | normal_grain_merge-0.1.3-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 26.9 kB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
423f7d211711b3265e2fb74c82b097aaa109e7e1e0b82dc2a44ede73a82a79e0
|
|
BLAKE2b-256 checksum How to use checksums |
dffc26ba9a8599d8cc1dd5a455fb1149f2441d7d2a7d3064cf9148be9697234c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp311-cp311-musllinux_1_2_x86_64.whl
| Download URL | normal_grain_merge-0.1.3-cp311-cp311-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 125.5 kB |
| Tags | CPython 3.11 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
3d8d63d08e040a41d22f7e51a9dec4d14333c0851e9685368411ae48628610d8
|
|
BLAKE2b-256 checksum How to use checksums |
b710c79c1e27de785b4d982658c17a974a9d0b9da17b6f9203fff7919d6d5e16
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | normal_grain_merge-0.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 129.7 kB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
011d944346088256e9863bcf09747d5811595a4783cb4a248d3410e10294e76c
|
|
BLAKE2b-256 checksum How to use checksums |
38546bc91db5d887d0b0098feec56f45e3e510ca8f1443cf663768163c96c1a0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp310-cp310-win_amd64.whl
| Download URL | normal_grain_merge-0.1.3-cp310-cp310-win_amd64.whl |
|---|---|
| Size | 26.9 kB |
| Tags | CPython 3.10 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
6b8777f6000a2c40d6462da699f6a0c078ddf2a5312673c155783f0d0b878d1e
|
|
BLAKE2b-256 checksum How to use checksums |
b4eafe3d41d32f247ae7b497c147d0b10c8b6c94e68831a2bc27867e88014d7a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp310-cp310-musllinux_1_2_x86_64.whl
| Download URL | normal_grain_merge-0.1.3-cp310-cp310-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 124.7 kB |
| Tags | CPython 3.10 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
df33c18207b83ad5eb34b8d7c112299e6de8b18db3a02c645cc71c282cfea0fe
|
|
BLAKE2b-256 checksum How to use checksums |
1b2c7fc5ad7c39278b6ecce86ad6f9b75d14e07a6321f07b86c74fa534484a82
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | normal_grain_merge-0.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 128.8 kB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
147fedacd170aef3e64a561cb11ea7f295eefe74b7759733e23005a3face4926
|
|
BLAKE2b-256 checksum How to use checksums |
911c71468c9159e970e159bad12b8e2ec2a4f3c54ff5da36a554531f56f30940
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp39-cp39-win_amd64.whl
| Download URL | normal_grain_merge-0.1.3-cp39-cp39-win_amd64.whl |
|---|---|
| Size | 26.9 kB |
| Tags | CPython 3.9 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
351e37e00e0b014939e066b70710b1a6198e7e4bd7f9c19450c5defbfe072647
|
|
BLAKE2b-256 checksum How to use checksums |
b3bdadb46ef68d09d5037a895dfaa0e1ac031ff07e588dde686d7520fe2db444
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp39-cp39-musllinux_1_2_x86_64.whl
| Download URL | normal_grain_merge-0.1.3-cp39-cp39-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 124.6 kB |
| Tags | CPython 3.9 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
05faac0b758278a317bccd21ea3c45779986eac68dd6fd050b4630316aee2019
|
|
BLAKE2b-256 checksum How to use checksums |
0a065269ac9826028e95431b0ecf1cddbf4f030ff9755fdf5faec46910467379
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | normal_grain_merge-0.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 128.6 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
272c1ded84b4c53ee9f8d390efe7fd16c1590fc5f7ea4f270ef93f5373e3010d
|
|
BLAKE2b-256 checksum How to use checksums |
a90664c18ec198882e79a803d0c04a4ccdb8af490b19e4bde5941cc58e0683e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp38-cp38-win_amd64.whl
| Download URL | normal_grain_merge-0.1.3-cp38-cp38-win_amd64.whl |
|---|---|
| Size | 26.8 kB |
| Tags | CPython 3.8 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
aae7d682b941b424251bdd0843ce13f6766f3e323ab69f5c0b38f345e719a575
|
|
BLAKE2b-256 checksum How to use checksums |
430fc7610735f5d38820f9baa8493cc51387ddc6a4ebb90d9528118bf35482d2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp38-cp38-musllinux_1_2_x86_64.whl
| Download URL | normal_grain_merge-0.1.3-cp38-cp38-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 126.0 kB |
| Tags | CPython 3.8 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
a5223f96ade8bb5aee6e7616f501805ea26ffa7b3a9e3b5bde9e5522594d378b
|
|
BLAKE2b-256 checksum How to use checksums |
3f1194a8be32ef8474fe998646fc5cd6548518f382fb4f04485b3894a46b8efb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / normal_grain_merge-0.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | normal_grain_merge-0.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 130.7 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
44dcc91cdb36dd707aba20b3f3348f3914ecb17a0e89e1f3704842b2cd94d73e
|
|
BLAKE2b-256 checksum How to use checksums |
0c2a1ad92001c244ae83c1e3af89ea7262262b4158472b0f88bb4cba824124dc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|