My goal for the project that I'm working on is to take in the content from a word document and then output a single image that contains bordered boxes that contain the segments of text that I've automatically funneled through with my code. Here is an example of what I need:
I've already managed to get 90% of the footwork done for this project thanks to a little bit of my own knowledge and a whole lot of knowledge from other people. My code already takes the text from word documents and takes what I want automatically. The problem arises when trying to mimic this image. I'm using Wand to create the image but I still can't quite get it to work. I know that I'm so close, but I'm not at all certain what I'm missing. The following is the code strictly for the image creation:
from wand.image import Image
from wand.drawing import Drawing
target_width = 500
target_height = 0
y_offset = 0
y_padding = 4
x_padding = 5
with Image(width=2000, height=2000, pseudo='xc:white') as img:
for match in find_matches(text=fullText):
ct += 1
with Drawing() as ctx:
ctx.font_size = 20
ctx.text_alignment = 'center'
words = match.split(" ")
words.append("\n" + str(ct))
word_count = len(words)
while True:
temp_text = rebuild_text(words, word_count)
metrics = ctx.get_font_metrics(img, temp_text, multiline=True)
if metrics.text_width > target_width:
word_count -= 1
else:
text = temp_text
target_height = int(metrics.text_height + 0.5)
break
ctx.push()
ctx.fill_color = 'white'
ctx.stroke_width = 3
ctx.stroke_color = 'black'
ctx.rectangle(2, y_offset + y_padding, width=2*x_padding+target_width,
height=6*y_padding+target_height)
ctx.pop()
ctx.text(x_padding + (target_width // 2), 16 + 6*y_padding+y_offset, text)
ctx(img)
y_offset = target_height + 100*y_padding + 7
img.trim()
img.save(filename='patdrawdemoTest.png')
I've tried messing with this code over and over again to no avail. I know that all of the text that I want is being passed through as I added a print statement to make sure of this already, and after messing with the code here and there, sometimes I find that there's lots of text that overlaps, but I can never get more than three bordered boxes. Here are some examples of the outputs that I've been able to get by changing values here and there:
I can't replicate the text-overlap output, however, the above are just some examples. I'm not sure if it helps at all, but the differences between those are the y-axis-related values for the text and rectangles and such.
The lines of text that I need are taken with the docx library in python which is then put into variables; it's not a simple string. Additionally, this code must work for any occasion; Whether it's 5 boxes of text, 2, 8, or 100, it must create an image with that many text boxes. The following is the text that I've parsed and that is passed through the code I have above:
Storing a first data related to an operation style of a transport in a first area 243
Storing a second data related to an operation style of the transport in a second area
244
Modifying functionality of the transport based on the combined energy consumption efficiency
245
Determining the combined energy consumption efficiency, wherein the determining comprises a blockchain consensus between a peer group comprising one or more of the transport, a server, and at least one other transport 246
Executing a smart contract to record the combined energy consumption efficiency on a blockchain, based on the blockchain consensus
247
I'll greatly appreciate any help I can get, as I'm completely stumped. Please let me know if I can be more clear or if there's something I'm missing to help you answer my question. Thanks.
@emconnville gave me the answer that I needed on another post a while before I posted this question, however there was an error that took me ages to see but this the answer to my question:
def to_chunks(words, size):
for idx in range(0, len(words), size):
yield words[idx:idx + size]
def rebuild_text(words, size, ct):
ret = "\n".join([" ".join(w) for w in to_chunks(words, size)])
ret += "\n" + ct
return ret
target_width = 375
target_height = 0
y_offset = 0
y_padding = 5
x_padding = 6
with Image(width=2000, height=5000, pseudo='xc:white') as img:
for match in find_matches(text=fullText):
ct += 1
with Drawing() as ctx:
ctx.font_size = 20
ctx.text_alignment = 'center'
words = match.split(" ")
word_count = len(words)
while True:
temp_text = rebuild_text(words, word_count, str(ct))
metrics = ctx.get_font_metrics(img, temp_text, multiline=True)
if metrics.text_width > target_width:
word_count -= 1
else:
text = temp_text
target_height = int(metrics.text_height + 1)
break
ctx.push()
ctx.fill_color = 'white'
ctx.stroke_width = 3
ctx.stroke_color = 'black'
ctx.rectangle(2, y_offset + y_padding, width=2*x_padding+target_width,
height=2*y_padding+target_height)
ctx.pop()
ctx.text(x_padding+2 + (target_width // 2), 10 + 4*y_padding+y_offset, text)
ctx(img)
y_offset += target_height + 4*y_padding - 2
img.trim()
img.save(filename='patdrawdemoTest.png')
The error was in this specific block of code:
ctx.text(x_padding+2 + (target_width // 2), 10 + 4*y_padding+y_offset, text)
ctx(img)
y_offset += target_height + 4*y_padding - 2
img.trim()
img.save(filename='patdrawdemoTest.png')
Where the "y_offset += target_height + 4*y_padding - 2" was originally just "y_offset = target..." So... Basically I was just missing the +=
I wish I wasn't blind.