Python PIL 减少字母间距

问题描述 投票:0回答:4

如何减小该文本的字母间距?我想让文本更加压缩几个像素。

我正在尝试制作一个透明的图像,上面有文字,我想将其推到一起。像这样,但透明:

from PIL import Image, ImageDraw, ImageFont

(W, H) = (140, 40)

#create transparent image
image = Image.new("RGBA", (140, 40), (0,0,0,0))

#load font
font = ImageFont.truetype("Arial.ttf", 30)
draw = ImageDraw.Draw(image)

text = "kpy7n"
w,h = font.getsize(text)

draw.text(((W-w)/2,(H-h)/2), text, font=font, fill=0)

image.save("transparent-image.png")
python python-imaging-library
4个回答
7
投票

此功能将为您自动解决所有痛苦。它是为了模拟 Photoshop 值而编写的,可以渲染行距(行之间的空间)以及跟踪(字符之间的空间)。

def draw_text_psd_style(draw, xy, text, font, tracking=0, leading=None, **kwargs):
    """
    usage: draw_text_psd_style(draw, (0, 0), "Test", 
                tracking=-0.1, leading=32, fill="Blue")

    Leading is measured from the baseline of one line of text to the
    baseline of the line above it. Baseline is the invisible line on which most
    letters—that is, those without descenders—sit. The default auto-leading
    option sets the leading at 120% of the type size (for example, 12‑point
    leading for 10‑point type).

    Tracking is measured in 1/1000 em, a unit of measure that is relative to 
    the current type size. In a 6 point font, 1 em equals 6 points; 
    in a 10 point font, 1 em equals 10 points. Tracking
    is strictly proportional to the current type size.
    """
    def stutter_chunk(lst, size, overlap=0, default=None):
        for i in range(0, len(lst), size - overlap):
            r = list(lst[i:i + size])
            while len(r) < size:
                r.append(default)
            yield r
    x, y = xy
    font_size = font.size
    lines = text.splitlines()
    if leading is None:
        leading = font.size * 1.2
    for line in lines:
        for a, b in stutter_chunk(line, 2, 1, ' '):
            w = font.getlength(a + b) - font.getlength(b)
            # dprint("[debug] kwargs")
            print("[debug] kwargs:{}".format(kwargs))
                
            draw.text((x, y), a, font=font, **kwargs)
            x += w + (tracking / 1000) * font_size
        y += leading
        x = xy[0]

它需要一个字体和一个绘制对象,可以通过以下方式获得:

font = ImageFont.truetype("Arial.ttf", 30)
draw = ImageDraw.Draw(image)

1
投票

您必须一个字符一个字符地绘制文本,然后在绘制下一个字符时更改 x 坐标

代码示例:

w,h = font.getsize("k")
draw.text(((W,H),"K", font=font, fill=0)
draw.text(((W+w)*0.7,H),"p", font=font, fill=0)
draw.text(((W+w*2)*0.7,H),"y", font=font, fill=0)
draw.text(((W+w*3)*1,H),"7", font=font, fill=0)
draw.text(((W+w*4)*0.8,H),"n", font=font, fill=0)

1
投票

你可以通过改变字距来做到这一点 - 我目前不知道如何使用 PIL 来做到这一点,但可以在终端中使用 ImageMagick 并使用 Python 使用 wand ,它是与 ImageMagick 的 Python 绑定.

首先,在终端中 - 查看参数

-kerning
,它先减三,然后加三:

magick -size 200x80 xc:black -gravity center -font "Arial Bold.ttf" -pointsize 50 -kerning -3 -fill white -draw "text 0,0 'kpy7n'" k-3.png

magick -size 200x80 xc:black -gravity center -font "Arial Bold.ttf" -pointsize 50 -kerning 3 -fill white -draw "text 0,0 'kpy7n'" k+3.png

并且,在 Python 中有些类似:

#!/usr/bin/env python3

# Needed this on macOS Monterey:
# export WAND_MAGICK_LIBRARY_SUFFIX="-7.Q16HDRI"
# export MAGICK_HOME=/opt/homebrew

from wand.image import Image
from wand.drawing import Drawing
from wand.font import Font

text = "kpy7n"

# Create a black canvas 400x120
with Image(width=400, height=120, pseudo='xc:black') as image:
    with Drawing() as draw:
        # Draw once in yellow with positive kerning
        draw.font_size = 50
        draw.font = 'Arial Bold.ttf'
        draw.fill_color = 'yellow'
        draw.text_kerning = 3.0
        draw.text(10, 80, text)
        draw(image)
        # Draw again in magenta with negative kerning
        draw.fill_color = 'magenta'
        draw.text_kerning = -3.0
        draw.text(200, 80, text)
        draw(image)
    image.save(filename='result.png')


0
投票

这可以通过逐个字符绘制文本并更改每个字符的坐标(以像素为单位)来完成。我们可以将

letter_spacing
设置为负值以减少空间,设置为正值以增加空间。

from PIL import Image, ImageDraw, ImageFont

# Load a font and create a drawing object
font = ImageFont.truetype("arial.ttf", 24)  # Change the font and size as needed

# Text to draw
text = "Custom Spacing"
textsize = font.getsize(text)

# Custom letter spacing in pixel values
# -1 means to reduce the default spacing by 1 pixel
letter_spacing = -1  

w = textsize[0] + int(len(text) * letter_spacing)
h = textsize[1]

img = Image.new("RGB", (w, h), color="white")
draw = ImageDraw.Draw(img)

# Initial x and y positions
x, y = 0, 0  
# Draw each character with custom spacing
for char in text:
    draw.text((x, y), char, fill="black", font=font)
    char_width, _ = draw.textsize(char, font=font)
    x += char_width + letter_spacing

# Display the image
img.show()
© www.soinside.com 2019 - 2024. All rights reserved.