我正在创建一个小的python程序,可以在128x48的小图像上绘制文本。 它仅适用于宽度仅为120的文本,但效果很好,但我不知道如何将较长的文本拆分为另一行。我该怎么做?
我尝试使用textwrap3,但无法将其与Pillow配合使用。
程序创建带有黑色背景和黄色居中文本的128x48图像文件,以后应在可输出480i的设备上查看,因此只需使文本多变小以适合其他文字宽度将无济于事。当前使用的字体是Arial 18。
以下是用于创建图片的当前代码:
funtion foo() {
var startTime = Utilities.formatDate(new Date(), ss.getSpreadsheetTimeZone(), 'yyyy-MM-dd\'T\'HH:mm:ss.SSS\'Z\'');
var endDate = new Date (new Date(startTime).getYear()+1, new Date(startTime).getMonth(), new Date(startTime).getDate());
var endTime = Utilities.formatDate(new Date(endDate), ss.getSpreadsheetTimeZone(), 'yyyy-MM-dd\'T\'HH:mm:ss.SSS\'Z\'');
var adResource = {
"kind": "dfareporting#ad",
"active": "true",
"archived": "false",
"campaignId": "23237909",
"name": "testApiAd",
"creativeRotation": {
"creativeAssignments": {
"active": "true",
"creativeId": "121312158",//.toString(),
"clickThroughUrl": {
"defaultLandingPage": "true",
//"type": "CREATIVE_ROTATION_TYPE_RANDOM",
//"weightCalculationStrategy": "WEIGHT_STRATEGY_EQUAL"
}
}
},
"deliverySchedule": {
"impressionRatio": "1",
"priority": "AD_PRIORITY_15",
"hardCutoff": "false"
},
"endTime": endTime,
"startTime": startTime,
"type": "AD_SERVING_STANDARD_AD",
"placementAssignments": {
"active": "true",
"placementId": "256185010",//.toString(),
//"sslRequired": "true"
}
}
var newAd = DoubleClickCampaigns.Ads.insert(adResource, profileID);
return newAd;
}
以上代码输出的图像如下:
宽度大于文本的长文本,则图像输出如下(LongerTextGoesHere):
所需结果应与此类似:
答案 0 :(得分:2)
如果使用 ImageMagick ,您可以非常简单地执行此操作,而无需编写任何Python代码,该软件安装在大多数Linux发行版中,并且可用于macOS和Windows。因此,只需在终端中:
convert -size 128x48 -background black -font Arial -fill yellow -gravity center caption:"Some Text" result.png
或者,使用更长的文本字符串:
convert -size 128x48 -background black -font Arial -fill yellow -gravity center caption:"Some Really Really Long Text" result.png
如果您真的要编写Python, Wand 是 ImageMagick 的Python绑定,并且函数名称将与上面使用的那些相同。
答案 1 :(得分:1)
这里有一些代码使用带有PIL / Pillow的二进制搜索将文本分成合适的部分。
def break_fix(text, width, font, draw):
if not text:
return
lo = 0
hi = len(text)
while lo < hi:
mid = (lo + hi + 1) // 2
t = text[:mid]
w, h = draw.textsize(t, font=font)
if w <= width:
lo = mid
else:
hi = mid - 1
t = text[:lo]
w, h = draw.textsize(t, font=font)
yield t, w, h
yield from break_fix(text[lo:], width, font, draw)
def fit_text(img, text, color, font):
width = img.size[0] - 2
draw = ImageDraw.Draw(img)
pieces = list(break_fix(text, width, font, draw))
height = sum(p[2] for p in pieces)
if height > img.size[1]:
raise ValueError("text doesn't fit")
y = (img.size[1] - height) // 2
for t, w, h in pieces:
x = (img.size[0] - w) // 2
draw.text((x, y), t, font=font, fill=color)
y += h
img = Image.new('RGB', (128, 48), color='black')
fit_text(img, 'LongerTextGoesHere', (255,255,0), Font)
img.show()