使用PIL制作梗图生成器:如何将文本精准置于图片中心下方?
Got it, let's sort out that text placement issue! The problem right now is that you're setting the text's top-left corner at the image center, which makes the text look off-center or not in the lower-middle spot you want. To get it perfectly centered below the image's center, we need to calculate the text's actual size first, then adjust the coordinates accordingly.
Here's how to adjust your code:
The key is using ImageDraw.textbbox() to get the exact dimensions of your text, then using those values to compute the correct x and y positions. This ensures the text stays centered horizontally and sits right below the image's center, no matter what text or font size you use.
Modified Code:
from PIL import Image, ImageDraw, ImageFont import os, random, datetime TEXT_FOR_MEMES = [ 'Отдохнули аче', 'Я бох а ты лох', 'Дада пугай мы же богатые', 'Именно поэтому донбасс может разволиться' ] os.chdir('direction.') # Make sure this path is correct for your environment def make_a_meme(): im = Image.open('pics_for_memes\\' + random.choice(os.listdir('pics_for_memes'))) draw_text = ImageDraw.Draw(im) font = ImageFont.truetype('Lobster.ttf', size=65) width = im.width height = im.height # Pick your text first so we can calculate its size selected_text = random.choice(TEXT_FOR_MEMES) # Get the bounding box of the text to find its width and height # (0,0) is a dummy position—we just need the size data text_bbox = draw_text.textbbox((0, 0), selected_text, font=font) text_width = text_bbox[2] - text_bbox[0] text_height = text_bbox[3] - text_bbox[1] # Calculate position: # - Horizontal center: image width minus text width, divided by 2 # - Vertical position: image center + half the text height + extra spacing (adjust 20 to your liking) x_pos = (width - text_width) / 2 y_pos = (height / 2) + (text_height / 2) + 20 # Draw the text at the calculated position draw_text.text((x_pos, y_pos), selected_text, fill='#ffffff', font=font) # Optional: save the meme instead of just showing it # im.save(f'memes\\meme_{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}.jpg') im.show() make_a_meme()
Key Changes Explained:
- Selected Text First: We pick the text before calculating size because each string in your list has different lengths—this ensures we get the exact dimensions for the text we're actually using.
- Text Bounding Box:
textbbox()returns a tuple(left, top, right, bottom)which lets us compute the exact width (right - left) and height (bottom - top) of the rendered text. - Position Calculation:
x_pos: Centers the text horizontally by shifting it left by half its own width from the image's midpoint.y_pos: Moves the text below the image center by adding half the text height (so the top of the text starts below center) plus an extra 20 pixels of spacing (you can adjust this number to move the text up or down more).
Bonus Tip:
If you want the text to sit closer to the bottom of the image instead of just below center, you can adjust the y_pos calculation to something like:
# Place text 50 pixels above the bottom edge y_pos = height - text_height - 50
This keeps it horizontally centered but anchored near the bottom, which is a common meme layout!
内容的提问来源于stack exchange,提问作者Magic Lake




