设置通道
This commit is contained in:
@ -3,6 +3,7 @@ from PIL import Image, ImageFilter, ImageDraw, ImageStat
|
||||
from PIL import ImageEnhance
|
||||
from PIL import ImageChops
|
||||
from PIL import ImageOps
|
||||
import cv2
|
||||
|
||||
from konabot.plugins.fx_process.color_handle import ColorHandle
|
||||
|
||||
@ -12,6 +13,7 @@ from konabot.plugins.fx_process.gradient import GradientGenerator
|
||||
import numpy as np
|
||||
|
||||
from konabot.plugins.fx_process.image_storage import ImageStorager
|
||||
from konabot.plugins.fx_process.math_helper import expand_contours
|
||||
from konabot.plugins.fx_process.types import SenderInfo, StoredInfo
|
||||
|
||||
class ImageFilterImplement:
|
||||
@ -1126,6 +1128,45 @@ class ImageFilterImplement:
|
||||
result = Image.alpha_composite(stroke_image, image)
|
||||
return result
|
||||
|
||||
# 基于形状的描边
|
||||
@staticmethod
|
||||
def apply_shape_stroke(image: Image.Image, stroke_width: int = 5, stroke_color: str = 'black') -> Image.Image:
|
||||
if image.mode != 'RGBA':
|
||||
image = image.convert('RGBA')
|
||||
|
||||
img = cv2.cvtColor(np.array(image), cv2.COLOR_RGBA2BGRA)
|
||||
|
||||
# 提取alpha通道
|
||||
alpha = img[:, :, 3]
|
||||
|
||||
# 应用阈值创建二值掩码
|
||||
_, binary_mask = cv2.threshold(alpha, 0.5, 255, cv2.THRESH_BINARY)
|
||||
|
||||
# 寻找轮廓
|
||||
contours, hierarchy = cv2.findContours(
|
||||
binary_mask,
|
||||
cv2.RETR_EXTERNAL,
|
||||
cv2.CHAIN_APPROX_SIMPLE
|
||||
)
|
||||
|
||||
# # 减少轮廓点数,以实现尖角效果
|
||||
# epsilon = 0.01 * cv2.arcLength(contours[0], True)
|
||||
# contours = [cv2.approxPolyDP(cnt, epsilon, True) for cnt in contours]
|
||||
|
||||
# 将轮廓点沿法线方向外扩
|
||||
expanded_contours = expand_contours(contours, stroke_width)
|
||||
|
||||
# 创建描边图像
|
||||
stroke_img = np.zeros_like(img)
|
||||
cv2.fillPoly(stroke_img, expanded_contours, ColorHandle.parse_color(stroke_color) + (255,))
|
||||
|
||||
# 轮廓图像转为PIL格式
|
||||
stroke_pil = Image.fromarray(cv2.cvtColor(stroke_img, cv2.COLOR_BGRA2RGBA))
|
||||
# 合并描边和原图
|
||||
result = Image.alpha_composite(stroke_pil, image)
|
||||
|
||||
return result
|
||||
|
||||
# 半调
|
||||
@staticmethod
|
||||
def apply_halftone(image: Image.Image, dot_size: int = 5) -> Image.Image:
|
||||
@ -1186,6 +1227,24 @@ class ImageFilterImplement:
|
||||
output.putalpha(alpha)
|
||||
|
||||
return output
|
||||
|
||||
# 设置通道
|
||||
@staticmethod
|
||||
def apply_set_channel(image: Image.Image, apply_image: Image.Image, channel: str = 'R', value: int = 255) -> Image.Image:
|
||||
if image.mode != 'RGBA':
|
||||
image = image.convert('RGBA')
|
||||
|
||||
if apply_image.mode != 'RGBA':
|
||||
apply_image = apply_image.convert('RGBA')
|
||||
|
||||
# 将 apply_image 的通道设置给 image
|
||||
image_arr = np.array(image)
|
||||
apply_arr = np.array(apply_image.resize(image.size, Image.Resampling.LANCZOS))
|
||||
channel_index = {'R':0, 'G':1, 'B':2, 'A':3}.get(channel.upper(), 0)
|
||||
image_arr[:, :, channel_index] = apply_arr[:, :, channel_index]
|
||||
|
||||
return Image.fromarray(image_arr, 'RGBA')
|
||||
|
||||
|
||||
|
||||
class ImageFilterEmpty:
|
||||
|
||||
Reference in New Issue
Block a user