首页 > 编程问答 >生成文本图像

生成文本图像

时间:2024-07-30 12:50:55浏览次数:10  
标签:python image fonts python-imaging-library arabic

我正在生成包含特定文本的图像。生成带有文本的图像是没有问题的,其中所有文本标记都来自一种字体。我想随机粗体一些单词,这需要我使用(2种字体)常规和粗体。

这是我解决这个问题的方法:

  1. 我将文本分成单词。
  2. 创建了一个字体掩码是随机的,无论是常规还是粗体。
  3. 我将所有掩码组合成一个图像,但是,因为它是一种从右到左的语言,所以我必须从右侧一个接一个地添加掩码。

问题 :是单词不在同一水平对齐线上!将不同蒙版组合成一张图像时出现问题。

image containing arabic text

应该如下所示:

image containing arabic text

from PIL import Image, ImageFont
import random

font_size = 60
font_bold_file = "fonts/Cairo/static/Cairo-Bold.ttf"
font_regular_file = "fonts/Cairo/Cairo-VariableFont_slnt,wght.ttf"
text_color = (0, 0, 0, 255)

font_regular = ImageFont.truetype(font_regular_file, size=font_size)
font_bold = ImageFont.truetype(font_bold_file, size=font_size)

text = "أبت أ ري عالم"
total_x = 0
total_y = 0
segments = []
for w in text.split(" "):

    mask = None
    if random.random() < 1:
        mask = font_regular.getmask(w + " ", "L")
    else:
        mask = font_regular.getmask(w + " ", "L")

    segments.append( (mask, mask.size[0]) )#
    total_x += mask.size[0]
    total_y = max(total_y, mask.size[1])

background_img = Image.new(mode="RGBA", size=(total_x, total_y), color=(255, 255, 0, 255))

acc_widths = 0
for seg in segments:
    mask = seg[0]
    width = seg[1]
    pivot_x = total_x - acc_widths - width
    acc_widths += width

    mask_req = (pivot_x, 0,  pivot_x + width, mask.size[1] )
    background_img.im.paste(text_color, mask_req, mask)


background_img.save("pic.png")


问题在于,正在为每个单词创建一个独立的蒙版,而没有考虑阿拉伯文字的基线对齐方式。阿拉伯语是一种脚本,某些字符连接在基线上方或下方。当前的方法将每个单词视为一个独立的单元,导致了不正确的垂直对齐方式。

以下是如何解决此问题的步骤:

  1. 计算最大基线: 在为各个单词创建蒙版之前,循环遍历文本中的所有单词,并使用 font.getbbox(word) 找到每个单词的边界框。找到所有边界框中 y 值(基线)的最大值。这将为提供用于对齐所有单词的公共基线。
  2. 使用公共基线创建蒙版: 生成每个单词的蒙版时,使用 font.getmask2(word, mode='L') 方法。 getmask2() 方法返回蒙版和边界框信息。使用步骤 1 中计算的公共基线,将单词蒙版垂直放置在图像中。
  3. 从右到左组合蒙版: 当前的方法已经正确地从右到左组合蒙版,因此可以继续使用该方法。

以下是更新后的代码:

from PIL import Image, ImageFont
import random

font_size = 60
font_bold_file = "fonts/Cairo/static/Cairo-Bold.ttf"
font_regular_file = "fonts/Cairo/Cairo-VariableFont_slnt,wght.ttf"
text_color = (0, 0, 0, 255)

font_regular = ImageFont.truetype(font_regular_file, size=font_size)
font_bold = ImageFont.truetype(font_bold_file, size=font_size)

text = "أبت أ ري عالم"

# Calculate maximum baseline
max_baseline = 0
for word in text.split(" "):
    bbox = font_regular.getbbox(word)
    max_baseline = max(max_baseline, bbox[1])

total_x = 0
total_y = max_baseline  # Use maximum baseline for image height
segments = []
for word in text.split(" "):
    mask = None
    if random.random() < 1:
        mask, bbox = font_regular.getmask2(word + " ", "L")
    else:
        mask, bbox = font_bold.getmask2(word + " ", "L")

    segments.append((mask, bbox[2]))  # Store width of the word
    total_x += bbox[2]  # Use actual word width for positioning

background_img = Image.new(mode="RGBA", size=(total_x, total_y), color=(255, 255, 0, 255))

acc_widths = 0
for seg in segments:
    mask = seg[0]
    width = seg[1]
    pivot_x = total_x - acc_widths - width
    acc_widths += width

    mask_req = (pivot_x, max_baseline - bbox[1], pivot_x + width, max_baseline - bbox[1] + mask.size[1])
    background_img.im.paste(text_color, mask_req, mask)

background_img.save("pic.png")

这段代码首先计算所有单词的公共基线,然后使用 getmask2() 方法和公共基线将每个单词放置在正确的位置。这可以确保所有单词都正确对齐到公共基线上,从而解决垂直对齐问题。

标签:python,image,fonts,python-imaging-library,arabic
From: 78803927

相关文章

  • python - 从文本生成音乐
    请给我一些建议为了解释一下,我输入“深度睡眠的睡眠音乐”,它将返回一个wav文件:https://www.youtube.com/watch?v=1wAdQhFJy54或者我给出一个wav文件,它会返回相同的现在这是我尝试过的:https://github.com/facebookresearch/audiocraft......
  • 从零开始的Python开发日记(7):短信验证功能开发流程
    短信验证功能开发流程在开发一个包含登录、注册以及短信验证的功能时,你需要遵循一个系统的开发流程。以下是实现这一功能的基本步骤,包括所需的技术和代码示例。1.环境配置首先,确保你的开发环境已经配置好,并安装了必要的库和工具。pipinstallfastapiuvicornsqlalche......
  • 【Python数值分析】革命:引领【数学建模】新时代的插值与拟合前沿技术
    目录​编辑第一部分:插值的基本原理及应用1.插值的基本原理1.1插值多项式1.2拉格朗日插值 1.3牛顿插值 1.4样条插值2.插值的Python实现2.1使用NumPy进行插值2.2使用SciPy进行插值2.2.1一维插值​编辑2.2.2二维插值3.插值的应用场景3.1数据平......
  • 在家用电脑上设置 Python 和 Jupyter,尝试打开 Jupyter 笔记本并显示错误,无法获取
    我有最新的Python版本3.12.4和以下版本的Jupyter:SelectedJupytercorepackages...IPython:8.26.0ipykernel:6.29.5ipywidgets:notinstalledjupyter_client:8.6.2jupyter_core:5.7.2jupyter_server:2.14.2jupyterlab......
  • Python - Reloading a module
    Eachmoduleisloadedintomemoryonlyonceduringaninterpretersessionorduringaprogramrun,regardlessofthenumberoftimesitisimportedintoaprogram.Ifmultipleimportsoccur,themodule’scodewillnotbeexecutedagainandagain.Suppose......
  • vscode python 3.7 pylance debugpy 插件 vsix
    可能报错  crashed5timesinthelast3minutes.Theserverwillnotberestarted.  ---pylance 可能报错  cannotreadpropertiesofundefinedreadingresolveEnvironment   --- debugger可能      vscodepython3.7调试没有反应......
  • Python获取秒级时间戳与毫秒级时间戳的方法[通俗易懂]
    参考资料:https://cloud.tencent.com/developer/article/21581481、获取秒级时间戳与毫秒级时间戳、微秒级时间戳代码语言:javascript复制importtimeimportdatetimet=time.time()print(t)#原始时间数据print(int(t))......
  • CEFPython
    在Tkinter界面中直接嵌入Selenium的浏览器视图并不是一件直接的事情,因为Selenium本身并不提供图形界面嵌入的功能。Selenium主要用于自动化web浏览器,但它并不直接控制浏览器窗口的显示方式,而是依赖于WebDriver来与浏览器交互。然而,你可以使用一些替代方案来在Tkinter应用中模拟或......
  • 《最新出炉》系列初窥篇-Python+Playwright自动化测试-58 - 文件下载
    1.简介前边几篇文章讲解完如何上传文件,既然有上传,那么就可能会有下载文件。因此宏哥就接着讲解和分享一下:自动化测试下载文件。可能有的小伙伴或者童鞋们会觉得这不是很简单吗,还用你介绍和讲解啊,不说就是访问到下载页面,然后定位到要下载的文件的下载按钮后,点击按钮就可以了。其实......
  • Python - Function Annotations
     deffunc(s:str,i:int,j:int)->str:returns[i:j]Theparametersissupposedtobeastring,soweplaceacolonaftertheparameternameandthenwritestr.Parametersiandjaresupposedtobeintegerssowewriteintforthem.Returntypeis......