我正在利用python中的魔杖来创建一个图像,它可以迭代自己,这样它就可以创建带有文本的黑色边框。以下是我的当前代码:
import re
from unicodedata import normalize
from docx import Document
from wand.image import Image
from wand.drawing import Drawing
from wand.font import Font
doc = Document("P.docx")
docText = []
for para in doc.paragraphs:
docText.append(para.text)
fullText = "\n".join(docText)
ct = 242
def get(source, begin, end):
try:
start = source.index(len(begin)) + len(begin)
finish = source.index(len(end), len(start))
return source[start:finish]
except ValueError:
return ""
def capitalize(string):
cap = ("".join(j[0].upper() + j[1:]) for j in string)
return cap
def find_matches(text):
return capitalize(
[
m
for m in re.findall(
r"^[^0-9]\s+([^.;]+\s*)+[.;]+", normalize("NFKD", text), re.MULTILINE
)
]
)
with Image(width=400, height=1000, pseudo='xc:white') as canvas:
left, top, width, height = 2, 2, 395, 131
for match in find_matches(text=fullText):
ct += 1
with Drawing() as context:
context.fill_color = 'black'
context.rectangle(left=left, top=top, width=width, height=height)
context.fill_color = 'white'
context.rectangle(left=(left+2), top=(top+2), width=(width-4), height=(height-4))
canvas.font = Font('/System/Library/Fonts/timesnewroman.ttf')
context(canvas)
canvas.caption(match + '\n' + str(ct), left=(left+5), top=top, width=(width-10), height=height,
gravity='center')
top += 135
canvas.crop(bottom=top)
canvas.save(filename='patdrawTest.png')通过这段代码,我能够产生以下输出:

这方面的问题显然是在字体大小方面缺乏一致性。下面是我的输出应该是什么样子(忽略框中的文本):

我唯一关心的是确保所有的文本都是相同的字体大小(大小12是很好的),那些边框调整文本大小。谢谢你的帮助!
编辑
根据提供的答案,下面是我的当前代码:
import re
from unicodedata import normalize
from docx import Document
from wand.image import Image
from wand.drawing import Drawing
doc = Document("P.docx")
docText = []
for para in doc.paragraphs:
docText.append(para.text)
fullText = "\n".join(docText)
ct = 242
def get(source, begin, end):
try:
start = source.index(len(begin)) + len(begin)
finish = source.index(len(end), len(start))
return source[start:finish]
except ValueError:
return ""
def capitalize(string):
cap = ("".join(j[0].upper() + j[1:]) for j in string)
return cap
def find_matches(text):
return capitalize(
[
m
for m in re.findall(
r"^[^0-9]\s+([^.;]+\s*)+[.;]+", normalize("NFKD", text), re.MULTILINE
)
]
)
def to_chunks(words, size):
for idx in range(0, len(words), size):
yield words[idx:idx + size]
def rebuild_text(words, size):
return "\n".join([" ".join(w) for w in to_chunks(words, size)])
target_width = 396
target_height = 0
y_offset = 0
y_padding = 10
x_padding = 5
with Image(width=1000, height=1000, pseudo='xc:white') as img:
for match in find_matches(text=fullText):
ct += 1
with Drawing() as ctx:
ctx.font_size = 16
ctx.text_alignment = 'center'
words = match.split(" ")
words.append("\n" + str(ct))
word_count = len(words)
while True:
temp_text = rebuild_text(words, word_count)
metrics = ctx.get_font_metrics(img, temp_text, multiline=True)
if metrics.text_width > target_width:
word_count -= 1
else:
text = temp_text
target_height = int(metrics.text_height + 0.5)
break
ctx.push()
ctx.fill_color = 'white'
ctx.stroke_width = 4
ctx.stroke_color = 'black'
ctx.rectangle(0, y_offset + y_padding, width=2*x_padding+target_width,
height=2*y_padding+target_height)
ctx.pop()
ctx.text(x_padding + (target_width // 2), 4*y_padding+y_offset, text)
ctx(img)
y_offset = target_height + 4*y_padding
img.trim()
img.save(filename='patdrawdemoTest.png')从这段代码中,我得到了以下输出:

我真不知道该怎么弥补这个奇怪的间距。第一个和第三个盒子看起来很棒,但是在第一个和第二个盒子之间有一个奇怪的空白,两边的边框不均匀,还有另外两个应该在那里的盒子,如最初的帖子所示。任何帮助都将不胜感激!
发布于 2021-06-25 15:36:13
我唯一关心的是确保所有的文本都是相同的字体大小(大小12是很棒的),那些边框调整到文本大小。谢谢你的帮助!
删除Image.caption方法(这与您想要的相反),并使用Drawing.text方法。Drawing类还有一个get_font_metrics方法来计算最终的重绘大小。这允许您格式化文本,检查它是否有效,然后绘制(或重新格式化&重复)。
以这个粗糙的例子为例。
content = [
"""Donec pretium vulputate sapien nec sagittis aliquam malesuada. Neque aliquam vestibulum morbi blandit cursus risus at ultrices mi.\n111""",
"""Adipiscing elit ut aliquam purus sit amet luctus venenatis. Eget mauris pharetra et ultrices neque ornare aenean. Viverra orci sagittis eu volutpat odio facilisis mauris. Vitae proin sagittis nisl rhoncus mattis rhoncus. Sapien nec sagittis aliquam malesuada bibendum arcu vitae.\n222"""
]
def to_chunks(words, size):
for idx in range(0, len(words), size):
yield words[idx:idx + size]
def rebuild_text(words, size):
return "\n".join([" ".join(w) for w in to_chunks(words, size)])
TARGET_WIDTH = 395
TARGET_HEIGHT = 0
BOX_Y_OFFSET = 0
BOX_Y_PADDING = 10
BOX_X_PADDING = 5
with Image(width=1000, height=1000, background='white') as img:
for text in content:
with Drawing() as ctx:
ctx.font_size = 16
ctx.text_alignment = 'center'
words = text.split(" ")
word_count = len(words)
while True:
tmp_text = rebuild_text(words, word_count)
metrics = ctx.get_font_metrics(img, tmp_text, multiline=True)
if metrics.text_width > TARGET_WIDTH:
word_count -= 1
else:
text = tmp_text
TARGET_HEIGHT = int(metrics.text_height + 0.5)
break
ctx.push()
ctx.fill_color = 'white'
ctx.stroke_width = 4
ctx.stroke_color = 'black'
ctx.rectangle(0, BOX_Y_OFFSET + BOX_Y_PADDING, width=2*BOX_X_PADDING+TARGET_WIDTH, height=2*BOX_Y_PADDING+TARGET_HEIGHT)
ctx.pop()
ctx.text(BOX_X_PADDING + (TARGET_WIDTH // 2), 4*BOX_Y_PADDING+BOX_Y_OFFSET, text)
ctx(img)
BOX_Y_OFFSET = TARGET_HEIGHT + 4*BOX_Y_PADDING
img.trim()
img.save(filename='output.png')

所有这些都是:
请记住。
https://stackoverflow.com/questions/68061619
复制相似问题