1

I have created a set of images in python utilizing PIL. In addition to this, I've implemented textwrap in order to put text onto the images I've created, however, they're not quite perfect. First, below are three examples of images I've created.

enter image description here enter image description here enter image description here

These three images have different widths, but I'd like them all to have the same width, whereas height isn't of concern and can be taller or smaller than each other; the width is the only thing that must remain consistent. In addition to this, I've used utf-8 encoding in order to get this text on the images, but I would like the font to look something more like the following

enter image description here

Also shown in the above image is how those boxes are stacked--That is how I'd like to have my final product. Rather than three separate images of bordered text, I'd like to have one single image containing those bordered boxes of text. Here is my current code for what I've output

for match in find_matches(text=fullText):
ct += 1
match_words = match.split(" ")
match = " ".join(match_words[:-1])
print(match)
W, H = 300, 300
base = Image.new("RGB", (W, H), (255, 255, 255))
draw = ImageDraw.Draw(base)
font = ImageFont.load_default()

current_h, pad = 50, 5

for key in textwrap.wrap(match, width=50):
    line = key.encode("ascii")
    w, h = draw.textsize(line, font=font)
    draw.text(((W - w) / 2, current_h), line, (0, 0, 0), font=font)
    current_h += h + pad
draw.text((W / 2, current_h), str(ct).encode("utf-8"), (0, 0, 0), font=font)
for count, matches in enumerate(match):
    base.save(f"{ct}C.png")
    bbox = ImageOps.invert(base).getbbox()
    trim = base.crop(bbox)
    patent = ImageOps.expand(trim, border=5, fill=(255, 255, 255))
    patent = ImageOps.expand(patent, border=3, fill=(0, 0, 0))
    patent.save(f"{ct}C.png")
    p_w, p_h = patent.size
    Image.open(result_fpath, "r")
    result.paste(patent)
    result.save(result_fpath)

Finally, this has to be an automated process. What I was thinking that could be done for the stacked boxes into a single image would be a for-loop that takes in the created images and then pastes them into an image of the same size as the first pasted image which resizes appropriately for each subsequent bordered box of text. I'd appreciate any help on this greatly.

1 Answer 1

2

I find this sort of thing much easier with ImageMagick, for which there are decent bindings available with wand.

Here's how you can do one image, just at the command-line in Terminal, showing the various parts in different colours so you can see what affects what:

magick -background yellow -gravity center -pointsize 24 -size 400x caption:"Detecting, by the component, that a replacement component has been added in the transport\n246C" -bordercolor magenta -border 10 -bordercolor cyan -border 5 result.png

enter image description here

And here's how you can do a few in one go:

magick -background white -gravity center -pointsize 24 -size 400x -bordercolor black \
 \( caption:"Detecting, by the component, that a replacement component has been added in the transport\n246C" -bordercolor black -border 5 -bordercolor white -border 5 \) \
 \( caption:"Detecting, by the component, that another component has been removed\n246D" -bordercolor black -border 5 -bordercolor white -border 5  \)  \
 \( caption:"Detecting, by any means, that another component has been replaced\n247K" -bordercolor black -border 5 -bordercolor white -border 5 \)  \
 -append result.png

enter image description here

Of course you can change the fonts, change the colours, read the captions from a file, use Unicode, space differently and/or do it all in Python with very similar-looking code - here is a link to an answer showing the approximate technique in wand in Python.

Sign up to request clarification or add additional context in comments.

2 Comments

This is really good, but I don't want the font size to change; only the height of the box that has been created. Additionally, is there an easy way to implement this into what I already have? I am trying to automate every process of this project, and as such changing the caption manually would be painful.
The font size is constant at 24 points in all the examples above - it only changes in the linked example which is slightly different from your case and which I only provided to give you a broad indicator of how similar code looks in Python. I'm not sure what you mean by "changing the caption manually", if your captions are in Python lists or dictionaries or files you can easily write them into images.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.