我正在尝试使用PILLOW绘制轮廓文本,以使字符重叠。但是,重叠是以“ z层”方式发生的,即字符仍然是不透明的,并不是真正的透明。
我的代码如下:
YC_CHARS = '0123456789'
YC_LENGTH = 6
YC_WIDTH = 200
YC_HEIGHT = 60
YC_BACKCOLOR = (255, 255, 255, 255)
YC_BACKCOLOR_TR = (255, 255, 255, 0)
YC_TEXTCOLOR = (0, 0, 0, 255)
YC_FONTS = ['fonts/antquab.ttf', 'fonts/ariblk.ttf', 'fonts/arlrdbd.ttf',
'fonts/comic.ttf', 'fonts/impact.ttf']
YC_FONTSZ = list(range(40, 51, 5))
def synth_captcha():
def outline_text(dr, pos, text, fnt, stroke, fill):
"Draw outline-style text"
dr.text((pos[0]-1, pos[1]), text, font=fnt, fill=stroke)
dr.text((pos[0]+1, pos[1]), text, font=fnt, fill=stroke)
dr.text((pos[0], pos[1]-1), text, font=fnt, fill=stroke)
dr.text((pos[0], pos[1]+1), text, font=fnt, fill=stroke)
dr.text(tuple(pos), text, font=fnt, fill=fill)
img = Image.new('RGB', (YC_WIDTH, YC_HEIGHT), color=YC_BACKCOLOR)
digit_offset = [random.randint(1, 3), random.randint(1, 10)]
digit_sz = [0, 0]
digit_offset = [1, 0]
for i in range(YC_LENGTH):
digit = random.choice(YC_CHARS)
font = ImageFont.truetype(random.choice(YC_FONTS), random.choice(YC_FONTSZ))
draw = ImageDraw.Draw(img, mode='RGBA')
digit_offset[0] += digit_sz[0] + random.randint(-digit_sz[0]//1.5, 0)
digit_sz = draw.textsize(digit, font=font)
digit_offset[1] = random.randint(1, max(2, YC_HEIGHT - digit_sz[1] - 2))
outline_text(draw, digit_offset, digit, font, YC_TEXTCOLOR, YC_BACKCOLOR_TR)
img.save('img.png')
答案 0 :(得分:0)
您需要use Image.alpha_composite
来绘制部分不透明的东西。
示例代码:
def synth_captcha():
def outline_text(dr, pos, text, fnt, stroke, fill):
"Draw outline-style text"
dr.text((pos[0]-1, pos[1]), text, font=fnt, fill=stroke)
dr.text((pos[0]+1, pos[1]), text, font=fnt, fill=stroke)
dr.text((pos[0], pos[1]-1), text, font=fnt, fill=stroke)
dr.text((pos[0], pos[1]+1), text, font=fnt, fill=stroke)
dr.text(tuple(pos), text, font=fnt, fill=fill)
img = Image.new('RGBA', (YC_WIDTH, YC_HEIGHT), color=YC_BACKCOLOR)
digit_offset = [random.randint(1, 3), random.randint(1, 10)]
digit_sz = [0, 0]
digit_offset = [1, 0]
for i in range(YC_LENGTH):
digit = random.choice(YC_CHARS)
font = ImageFont.truetype(random.choice(YC_FONTS), random.choice(YC_FONTSZ))
txt = Image.new('RGBA', img.size, YC_BACKCOLOR_TR)
draw = ImageDraw.Draw(txt)
digit_offset[0] += digit_sz[0] + random.randint(-digit_sz[0]//1.5, 0)
digit_sz = draw.textsize(digit, font=font)
digit_offset[1] = random.randint(1, max(2, YC_HEIGHT - digit_sz[1] - 2))
outline_text(draw, digit_offset, digit, font, YC_TEXTCOLOR, YC_BACKCOLOR_TR)
img = Image.alpha_composite(img, txt)
return img
编辑:将YC_BACKCOLOR_TR
更改为(0, 0, 0, 0)
会产生更立体的笔触。我不确定为什么,但是它可能与dr.text
处理字符边界处的透明度的方式有关。
我的猜测是,它只是将RGBA值混合为4d向量,因此对于通常以50%不透明度绘制的像素,将(0, 0, 0, 255)
与(255, 255, 255, 0)
混合会产生(128, 128, 128, 128)
。当该像素以alpha方式合成到白色背景上时,它变成(192, 192, 192, 255)
,比应有的灰度要浅。我认为在您的情况下,仅在Alpha贴图(即YC_BACKCOLOR_TR = (0, 0, 0, 0)
)上工作是一种合理的方法,但我很好奇是否有更好或概念上更简单的方法可以做到这一点。