@egeres 使用与目标颜色的距离来创建 alpha 值的方法非常简洁,并且可以创建更好的结果。这里使用 numpy:
import numpy as np
import matplotlib.pyplot as plt
def color_to_alpha(im, target_color):
alpha = np.max(
[
np.abs(im[..., 0] - target_color[0]),
np.abs(im[..., 1] - target_color[1]),
np.abs(im[..., 2] - target_color[2]),
],
axis=0,
)
ny, nx, _ = im.shape
im_rgba = np.zeros((ny, nx, 4), dtype=im.dtype)
for i in range(3):
im_rgba[..., i] = im[..., i]
im_rgba[..., 3] = alpha
return im_rgba
target_color = (0.0, 0.0, 0.0)
im = plt.imread("img.png")
im_rgba = color_to_alpha(im, target_color)
为了完整起见,我在下面与应用于 matplotlib 徽标的基于掩码的版本进行了比较:
from pathlib import Path
import matplotlib.pyplot as pl
import numpy as np
def color_to_alpha(im, alpha_color):
alpha = np.max(
[
np.abs(im[..., 0] - alpha_color[0]),
np.abs(im[..., 1] - alpha_color[1]),
np.abs(im[..., 2] - alpha_color[2]),
],
axis=0,
)
ny, nx, _ = im.shape
im_rgba = np.zeros((ny, nx, 4), dtype=im.dtype)
for i in range(3):
im_rgba[..., i] = im[..., i]
im_rgba[..., 3] = alpha
return im_rgba
def color_to_alpha_mask(im, alpha_color):
mask = (im[..., :3] == alpha_color).all(axis=2)
alpha = np.where(mask, 0, 255)
ny, nx, _ = im.shape
im_rgba = np.zeros((ny, nx, 4), dtype=im.dtype)
im_rgba[..., :3] = im
im_rgba[..., -1] = alpha
return im_rgba
# load example from images included with matplotlib
fn_img = Path(plt.__file__).parent / "mpl-data" / "images" / "matplotlib_large.png"
im = plt.imread(fn_img)[..., :3] # get rid of alpha channel already in image
target_color = [1.0, 1.0, 1.0]
im_rgba = color_to_alpha(im, target_color)
im_rgba_masked = color_to_alpha_mask(im, target_color)
fig, axes = plt.subplots(ncols=3, figsize=(12, 4))
[ax.set_facecolor("lightblue") for ax in axes]
axes[0].imshow(im)
axes[0].set_title("original")
axes[1].imshow(im_rgba)
axes[1].set_title("using distance to color")
axes[2].imshow(im_rgba_masked)
axes[2].set_title("mask on color")
