3

I would like to take a text file with about 1,000 lines and create a separate png image for each line in the file using possibly ImageMagick convert. The image should be 1920x1080 with a black background and white text. I am able to get the list (all at once) onto an image using this command:

convert -size 1980x1020 xc:black -font Play-Regular.ttf -pointsize 85 -fill white -gravity center -draw "text 0,0 '$(cat list.txt)'" image.png

I also tried to create a bash file, to iterate each line:

#!/bin/bash
File="list.txt"
Lines=$(cat $File)
for Line in $Lines
do
convert -size 1980x1020 xc:black -font Play-Regular.ttf -pointsize 85 -fill white -gravity center -draw "text 0,0 '$(cat Line)'" $line.png
done

I feel like I am getting closer, but my bash-fu is weak and the command threw several errors.

4
  • 1
    Line is already the line you want to print, so don't cat it, but simply '$Line'? This should work, but I think it's better to switch the loop from first storing the file contents in a variable to something like while read Line; do … <"$File"
    – Philippos
    May 9, 2022 at 10:10
  • 3
    See mywiki.wooledge.org/BashFAQ/001 for how to process a file line-by-line and why using for for this purpose is problematic.
    – Bodo
    May 9, 2022 at 10:34
  • 1
    I suspect you want 1920x1080 rather than 1980x1020 May 9, 2022 at 10:57
  • Whew thanks for the catch, will do resizes using mogrify but, you're spot on! Gratis! May 9, 2022 at 11:07

2 Answers 2

5

You'd need first to convert that line in the format expected by convert. Here with zsh instead of bash:

#! /bin/zsh -
file=list.txt

typeset -Z4 n=1 # line counter 0-padded to length 4.
set -o extendedglob

while IFS= read -ru3 line; do
  # remove NUL characters if any:
  line=${line//$'\0'}
  # escape ' and \ characters with \:
  escaped_line=${line//(#m)[\'\\]/\\$MATCH}

  convert -size 1920x1080 \
          xc:black \
          -font Play-Regular.ttf \
          -pointsize 85 \
          -fill white \
          -gravity center \
          -draw "text 0,0 '$escaped_line'" line$n.png
  (( n++ ))
done 3< $file
-1

Thanks for the help! Great tutorial, a little trial and error, and my first true BASH is running and making images! Here's what worked:

#!/bin/bash
file="list.txt"
while read -r line; do
convert -size 1980x1020 xc:black -font Play-Regular.ttf -pointsize 105 -fill white -gravity center -draw "text 0,0 '$line'" $line.png
done < "$file"

It's so exciting when your code, actually executes!

2
  • 3
    You should quote $line.png. You would also get into trouble if any line has a single-quote and mangled if back-slash. Something like escaped_line=${line//\\/\\\\}; escaped_line=${line//\'/\\\'}
    – ibuprofen
    May 9, 2022 at 12:31
  • 1
    … and that should obviously be: escaped_line=${line//\\/\\\\}; escaped_line=${escaped_line//\'/\\\'} :P
    – ibuprofen
    May 9, 2022 at 21:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .