有没有办法用PIL中的暗线勾勒出文字?

use*_*351 10 python image image-processing python-imaging-library python-3.x

我正在使用python/PIL在一组PNG图像上写文本.我能够得到我想要的字体,但我现在想用黑色勾勒出文字.

这就是我所拥有的:正如你所看到的,如果背景为白色,则很难阅读.

在此输入图像描述

这是目标:

在此输入图像描述

有没有办法用PIL实现这一目标?如果没有,我愿意听取其他建议,但没有承诺,因为我已经使用PIL在python中开始了一个大项目.

处理图像绘制的代码部分:

for i in range(0,max_frame_int + 1):
    writeimg = Image.open("frameinstance" + str(i) + ".png")
    newimg = Image.new("RGB", writeimg.size)
    newimg.paste(writeimg)
    width_image = newimg.size[0]
    height_image = newimg.size[1]
    draw = ImageDraw.Draw(newimg)
    # font = ImageFont.truetype(<font-file>, <font-size>)
    for font_size in range(50, 0, -1):
        font = ImageFont.truetype("impact.ttf", font_size)
        if font.getsize(meme_text)[0] <= width_image:
            break
    else:
        print('no fonts fit!')

    # draw.text((x, y),"Sample Text",(r,g,b))
    draw.text((int(0.05*width_image), int(0.7*height_image)),meme_text,(255,255,255),font=font)
    newimg.save("newimg" + str(i) +".png")
Run Code Online (Sandbox Code Playgroud)

Dua*_*ane 12

PIL 现在支持此功能。以下代码适用于 9.2.0

from PIL import Image, ImageDraw, ImageFont

caption = 'I need to update my Pillow'
img = Image.open('./example-img.jpg')
d = ImageDraw.Draw(img)
font = ImageFont.truetype('impact.ttf', size=50)
d.text((10, 400), caption, fill='white', font=font,
       stroke_width=2, stroke_fill='black')
img.save('example-output.jpg')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


jac*_*nye 11

您可以使用PIL查看此文本大纲

  • 要单独提供链接,您可以使用评论部分.如果您有答案或要点证明,请使用答案部分. (4认同)
  • 顺便说一下,这是一个有用的链接:) (2认同)
  • 该解决方案的问题在像素尺寸较高时变得明显。相反,最好使用 ImageDraw.text 支持的内置“中风宽度”和“中风填充”参数:https://pillow.readthedocs.io/en/stable/reference/ImageDraw.html#PIL.ImageDraw.ImageDraw。文本 (2认同)

bil*_*ila 8

检查stroke_width选项,它实现了stroke/border/outline效果。为了shadow效果,您可以使用小的偏移量进行绘制。Bellow 是为图像添加字幕的示例。

#!/usr/bin/env python
from PIL import Image, ImageDraw, ImageFont


def add_subtitle(
    bg,
    text="nice",
    xy=("center", 20),
    font="font/SourceHanSansSC-Regular.otf",
    font_size=53,
    font_color=(255, 255, 255),
    stroke=2,
    stroke_color=(0, 0, 0),
    shadow=(4, 4),
    shadow_color=(0, 0, 0),
):
    """draw subtitle on image by pillow
    Args:
        bg(PIL image): image to add subtitle
        text(str): subtitle
        xy(tuple): absolute top left location of subtitle
        ...: extra style of subtitle
    Returns:
        bg(PIL image): image with subtitle
    """
    stroke_width = stroke
    xy = list(xy)
    W, H = bg.width, bg.height
    font = ImageFont.truetype(str(font), font_size)
    w, h = font.getsize(text, stroke_width=stroke_width)
    if xy[0] == "center":
        xy[0] = (W - w) // 2
    if xy[1] == "center":
        xy[1] = (H - h) // 2
    draw = ImageDraw.Draw(bg)
    if shadow:
        draw.text(
            (xy[0] + shadow[0], xy[1] + shadow[1]), text, font=font, fill=shadow_color
        )
    draw.text(
        (xy[0], xy[1]),
        text,
        font=font,
        fill=font_color,
        stroke_width=stroke_width,
        stroke_fill=stroke_color,
    )
    return bg


if __name__ == "__main__":
    bg = Image.open("./Screenshot_20200626-131218.png")
    bg = add_subtitle(bg)
    bg.save("out.png")
Run Code Online (Sandbox Code Playgroud)


小智 6

因此,这就是我需要为帧计数器处理此问题的方式。如果您开始尝试提高厚度,则需要多加注意,以弥补您遗失的区域。

from PIL import Image,ImageDraw,ImageFont
import os

#setting varibles
imgFile = "frame_0.jpg"
output = "frame_edit_0.jpg"
font = ImageFont.truetype("arial.ttf", 30)
text = "SEQ_00100_SHOT_0004_FR_0001"
textColor = 'white'
shadowColor = 'black'
outlineAmount = 3

#open image
img = Image.open(imgFile)
draw = ImageDraw.Draw(img)

#get the size of the image
imgWidth,imgHeight = img.size

#get text size
txtWidth, txtHeight = draw.textsize(text, font=font)

#get location to place text
x = imgWidth - txtWidth - 100
y = imgHeight - txtHeight - 100

#create outline text
for adj in range(outlineAmount):
    #move right
    draw.text((x-adj, y), text, font=font, fill=shadowColor)
    #move left
    draw.text((x+adj, y), text, font=font, fill=shadowColor)
    #move up
    draw.text((x, y+adj), text, font=font, fill=shadowColor)
    #move down
    draw.text((x, y-adj), text, font=font, fill=shadowColor)
    #diagnal left up
    draw.text((x-adj, y+adj), text, font=font, fill=shadowColor)
    #diagnal right up
    draw.text((x+adj, y+adj), text, font=font, fill=shadowColor)
    #diagnal left down
    draw.text((x-adj, y-adj), text, font=font, fill=shadowColor)
    #diagnal right down
    draw.text((x+adj, y-adj), text, font=font, fill=shadowColor)

#create normal text on image
draw.text((x,y), text, font=font, fill=textColor)

img.save(output)
print 'Finished'
os.startfile(output)
Run Code Online (Sandbox Code Playgroud)