0

I'm trying to convert text into an image with pillow and python, with the help of this answer + I added some lines to make the text split into columns in order to make a square image because the code of the answer shows the text in just one tall column. here's an example output of a large text file(it's just a thumbnail because the original image is large): current result

you can see in the bottom right that there's empty space, that happens because the text lines are not split evenly, I tried everything, I hope someone can help me fix it.

here's how I want it to look: (without the empty space in the bottom right)best result to do this, the script must split the lines evenly between the columns.

THANK YOU

here's the code

import PIL, math, os
import PIL.Image
import PIL.ImageFont
import PIL.ImageOps
import PIL.ImageDraw

def text_image(text_path, font_path=None):
    with open(text_path) as text_file:
        lines = tuple(l.rstrip() for l in text_file.readlines())

    large_font = 15
    font_path = font_path or 'font.ttf'
    try:
        font = PIL.ImageFont.truetype(font_path, size=large_font)
    except IOError:
        font = PIL.ImageFont.load_default()
        print('Could not use chosen font. Using default.')

    pt2px = lambda pt: int(round(pt * 96.0 / 72))
    max_width_line = max(lines, key=lambda s: font.getsize(s)[0])

    test_string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    max_height = pt2px(font.getsize(test_string)[1])
    max_width = pt2px(font.getsize(max_width_line)[0])
    mw = font.getsize(max_width_line)[0]
    mh = font.getsize(max_width_line)[1]
    height = max_height * len(lines)
    width = int(round(max_width + 40))
    
    block = int(mw/mh)
    squareBlock = int(math.sqrt(len(lines)/(mw/mh))) + 1
    
    squareImageSize = block * squareBlock * block
    
    image = PIL.Image.new('L', (squareImageSize, squareImageSize), color=PIXEL_OFF)
    draw = PIL.ImageDraw.Draw(image)
    
    vertical_position = 20
    horizontal_position = 20
    line_spacing = int(round(max_height * 0.8))
    i = 0
    for e, line in enumerate(lines):
        draw.text((horizontal_position, vertical_position),
                  line, fill=PIXEL_ON, font=font)
        vertical_position += line_spacing
        
        if e % block == 0 and not e==0:
            i+=1
        if i == squareBlock:
            i = 0
            horizontal_position += mw - 20
            vertical_position = 20

    a, b, c, d = PIL.ImageOps.invert(image).getbbox()
    image = image.crop((0,0,c+20,d+20))
    
    return image
Mhmd Admn
  • 357
  • 3
  • 10
  • 1
    It's not very clear what you are actually trying to do. Nor what the problem is. And you can share proper resolution images - up to 2MB- or use Dropbox or Google Drive or similar. – Mark Setchell Jul 30 '21 at 20:09
  • @MarkSetchell thank you, I edited the question. I added the result that I want to see – Mhmd Admn Jul 30 '21 at 20:20
  • 1
    Sorry, I still see a low resolution input image and still have no idea what you are hoping to do. – Mark Setchell Jul 30 '21 at 21:13

0 Answers0