This commit is contained in:
@ -1,15 +1,167 @@
|
||||
from PIL import Image, ImageFilter
|
||||
from PIL import ImageEnhance
|
||||
|
||||
class ImageFilterUtils:
|
||||
from konabot.plugins.fx_process.color_handle import ColorHandle
|
||||
|
||||
import math
|
||||
|
||||
class ImageFilterImplement:
|
||||
@staticmethod
|
||||
def apply_blur(image: Image.Image, radius: float = 5) -> Image.Image:
|
||||
"""对图像应用模糊效果
|
||||
def apply_blur(image: Image.Image, radius: float = 10) -> Image.Image:
|
||||
return image.filter(ImageFilter.GaussianBlur(radius))
|
||||
|
||||
# 马赛克
|
||||
@staticmethod
|
||||
def apply_mosaic(image: Image.Image, pixel_size: int = 10) -> Image.Image:
|
||||
if pixel_size <= 0:
|
||||
pixel_size = 1
|
||||
# 缩小图像
|
||||
small_image = image.resize(
|
||||
(image.width // pixel_size, image.height // pixel_size),
|
||||
Image.Resampling.NEAREST
|
||||
)
|
||||
# 放大图像
|
||||
return small_image.resize(image.size, Image.Resampling.NEAREST)
|
||||
|
||||
@staticmethod
|
||||
def apply_contour(image: Image.Image) -> Image.Image:
|
||||
return image.filter(ImageFilter.CONTOUR)
|
||||
|
||||
@staticmethod
|
||||
def apply_sharpen(image: Image.Image) -> Image.Image:
|
||||
return image.filter(ImageFilter.SHARPEN)
|
||||
|
||||
@staticmethod
|
||||
def apply_edge_enhance(image: Image.Image) -> Image.Image:
|
||||
return image.filter(ImageFilter.EDGE_ENHANCE)
|
||||
|
||||
@staticmethod
|
||||
def apply_emboss(image: Image.Image) -> Image.Image:
|
||||
return image.filter(ImageFilter.EMBOSS)
|
||||
|
||||
@staticmethod
|
||||
def apply_find_edges(image: Image.Image) -> Image.Image:
|
||||
return image.filter(ImageFilter.FIND_EDGES)
|
||||
|
||||
@staticmethod
|
||||
def apply_smooth(image: Image.Image) -> Image.Image:
|
||||
return image.filter(ImageFilter.SMOOTH)
|
||||
|
||||
# 反色
|
||||
@staticmethod
|
||||
def apply_invert(image: Image.Image) -> Image.Image:
|
||||
# 确保图像是RGBA模式,保留透明度通道
|
||||
if image.mode != 'RGBA':
|
||||
image = image.convert('RGBA')
|
||||
r, g, b, a = image.split()
|
||||
r = r.point(lambda i: 255 - i)
|
||||
g = g.point(lambda i: 255 - i)
|
||||
b = b.point(lambda i: 255 - i)
|
||||
return Image.merge('RGBA', (r, g, b, a))
|
||||
|
||||
# 黑白灰度
|
||||
@staticmethod
|
||||
def apply_black_white(image: Image.Image) -> Image.Image:
|
||||
# 保留透明度通道
|
||||
if image.mode != 'RGBA':
|
||||
image = image.convert('RGBA')
|
||||
r, g, b, a = image.split()
|
||||
gray = Image.merge('RGB', (r, g, b)).convert('L')
|
||||
return Image.merge('RGBA', (gray, gray, gray, a))
|
||||
|
||||
# 阈值
|
||||
@staticmethod
|
||||
def apply_threshold(image: Image.Image, threshold: int = 128) -> Image.Image:
|
||||
# 保留透明度通道
|
||||
if image.mode != 'RGBA':
|
||||
image = image.convert('RGBA')
|
||||
r, g, b, a = image.split()
|
||||
gray = Image.merge('RGB', (r, g, b)).convert('L')
|
||||
bw = gray.point(lambda x: 255 if x >= threshold else 0, '1')
|
||||
return Image.merge('RGBA', (bw.convert('L'), bw.convert('L'), bw.convert('L'), a))
|
||||
|
||||
# 对比度
|
||||
@staticmethod
|
||||
def apply_contrast(image: Image.Image, factor: float = 1.5) -> Image.Image:
|
||||
enhancer = ImageEnhance.Contrast(image)
|
||||
return enhancer.enhance(factor)
|
||||
|
||||
# 亮度
|
||||
@staticmethod
|
||||
def apply_brightness(image: Image.Image, factor: float = 1.5) -> Image.Image:
|
||||
enhancer = ImageEnhance.Brightness(image)
|
||||
return enhancer.enhance(factor)
|
||||
|
||||
# 色彩
|
||||
@staticmethod
|
||||
def apply_color(image: Image.Image, factor: float = 1.5) -> Image.Image:
|
||||
enhancer = ImageEnhance.Color(image)
|
||||
return enhancer.enhance(factor)
|
||||
|
||||
# 三色调
|
||||
@staticmethod
|
||||
def apply_to_color(image: Image.Image, color: str = 'rgb(255,0,0)') -> Image.Image:
|
||||
if image.mode != 'RGBA':
|
||||
image = image.convert('RGBA')
|
||||
# 转为灰度图
|
||||
gray = image.convert('L')
|
||||
# 获取目标颜色的RGB值
|
||||
rgb_color = ColorHandle.parse_color(color)
|
||||
# 高光默认为白色,阴影默认为黑色
|
||||
highlight = (255, 255, 255)
|
||||
shadow = (0, 0, 0)
|
||||
# 创建新的图像
|
||||
new_image = Image.new('RGBA', image.size)
|
||||
width, height = image.size
|
||||
for x in range(width):
|
||||
for y in range(height):
|
||||
lum = gray.getpixel((x, y))
|
||||
# 计算新颜色
|
||||
new_r = int((rgb_color[0] * lum + shadow[0] * (highlight[0] - lum)) / 255)
|
||||
new_g = int((rgb_color[1] * lum + shadow[1] * (highlight[1] - lum)) / 255)
|
||||
new_b = int((rgb_color[2] * lum + shadow[2] * (highlight[2] - lum)) / 255)
|
||||
a = image.getpixel((x, y))[3] # 保留原图的透明度
|
||||
new_image.putpixel((x, y), (new_r, new_g, new_b, a))
|
||||
return new_image
|
||||
|
||||
# 缩放
|
||||
@staticmethod
|
||||
def apply_resize(image: Image.Image, scale: float = 1.5) -> Image.Image:
|
||||
if scale <= 0:
|
||||
scale = 1.0
|
||||
new_size = (int(image.width * scale), int(image.height * scale))
|
||||
return image.resize(new_size, Image.Resampling.LANCZOS)
|
||||
|
||||
# 波纹
|
||||
@staticmethod
|
||||
def apply_wave(image: Image.Image, amplitude: float = 5, wavelength: float = 20) -> Image.Image:
|
||||
width, height = image.size
|
||||
new_image = Image.new('RGBA', (width, height))
|
||||
for x in range(width):
|
||||
for y in range(height):
|
||||
offset_x = int(amplitude * math.sin(2 * math.pi * y / wavelength))
|
||||
offset_y = int(amplitude * math.cos(2 * math.pi * x / wavelength))
|
||||
new_x = x + offset_x
|
||||
new_y = y + offset_y
|
||||
if 0 <= new_x < width and 0 <= new_y < height:
|
||||
new_image.putpixel((x, y), image.getpixel((new_x, new_y)))
|
||||
else:
|
||||
new_image.putpixel((x, y), (0, 0, 0, 0)) # 透明像素
|
||||
return new_image
|
||||
|
||||
参数:
|
||||
image: 要处理的Pillow图像对象
|
||||
radius: 模糊半径,值越大模糊效果越明显
|
||||
|
||||
返回:
|
||||
处理后的Pillow图像对象
|
||||
"""
|
||||
return image.filter(ImageFilter.GaussianBlur(radius))
|
||||
def apply_color_key(image: Image.Image, target_color: str = 'rgb(255,0,0)', tolerance: int = 60) -> Image.Image:
|
||||
if image.mode != 'RGBA':
|
||||
image = image.convert('RGBA')
|
||||
target_rgb = ColorHandle.parse_color(target_color)
|
||||
width, height = image.size
|
||||
new_image = Image.new('RGBA', (width, height))
|
||||
for x in range(width):
|
||||
for y in range(height):
|
||||
r, g, b, a = image.getpixel((x, y))
|
||||
# 计算与目标颜色的距离
|
||||
distance = math.sqrt((r - target_rgb[0]) ** 2 + (g - target_rgb[1]) ** 2 + (b - target_rgb[2]) ** 2)
|
||||
if distance <= tolerance:
|
||||
new_image.putpixel((x, y), (r, g, b, 0)) # 设置为透明
|
||||
else:
|
||||
new_image.putpixel((x, y), (r, g, b, a)) # 保留原像素
|
||||
return new_image
|
||||
Reference in New Issue
Block a user