Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
210 views
in Technique[技术] by (71.8m points)

python - How do I dynamically size images to the size of the text using PIL (or anything else)?

I want the size of the image that I create to dynamically change according to the string being written into it. What my code currently does is, with PIL and docx implementation, take data from a word document that I put into a single string from which it is parsed through some loops in order to output images for specific excerpts of text from the string, that being from a keyword all the way to a part number. For the sake of only showing what's completely necessary, here is the part of my code that I need help with:

for match in find_matches(text=docText, keywords=("responsive", "detecting", "providing")):
    W, H = 300, 300
    body = Image.new('RGB', (W, H), (255, 255, 255))
    border = Image.new('RGB', (W + 4, H + 4), (0, 0, 0))
    border.save('border.png')
    body.save('body.png')
    patent = Image.open('border.png')
    patent.paste(body, (2, 2))
    draw = ImageDraw.Draw(patent)
    font = ImageFont.load_default()
    current_h, pad = 100, 20

    for key in textwrap.wrap(match, width=45):
        line = key.encode('utf-8')
        w, h = draw.textsize(line, font=font)
        draw.text(((W - w) / 2, current_h), line, (0, 0, 0), font=font)
        current_h += h + pad
    for count, matches in enumerate(match):
        patent.save(f'{match}.png')

From this and the rest of my code, I also have this source document file, which I'll just show an image of:

Source Doc

Finally, from the current code I have, I'm able to get the following image outputs:

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

The goal is to be able to remove all of the whitespace from the images, or as much of it as possible, and have this added to the automated process of creating the images so that there is as little whitespace as possible and just have the image border fit right around the text in the same box-like format. As an added bonus, and this isn't at all required since I'm primarily asking about the whitespace issue, if there's a quick fix to make the "249C" and similar part numbers be on the very last line with no other text joining them, that would also be great, but once again my primary issue is making the images fit to the size of the text.

This is an example of what I want my output to look like, except that each box is its own image:

Sample Output

question from:https://stackoverflow.com/questions/65545751/how-do-i-dynamically-size-images-to-the-size-of-the-text-using-pil-or-anything

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It seems that you have the full control of the text on the image, which means if you add the text to an image with white background, you could know exactly where the black pixels are. With this image, you could determine the "border" by counting the black pixels in each rows/columns and you could get the position of the border.

For example:

image  = cv2.imread("image-file")
grayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
nrows, ncols = grayImage.shape
isBlackPixelMat = grayImage < 100
numOfPixelInColumn = isBlackPixelMat.sum(axis=0)

# find start column
k = 0;
while k < ncols and numOfPixelInColumn[k] == 0:
    k += 1
startColumn = k

# find end column
k = ncols - 1

while k > 0 and numOfPixelInColumn[k] == 0:
    k -= 1
endColumn = k

# draw lines

cv2.line(image, (startColumn, 0), (startColumn, ncols - 1), color=(255, 0, 0))
cv2.line(image, (endColumn, 0), (endColumn, ncols - 1), color=(255, 0, 0))

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...