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 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 at 10:34
  • 1
    I suspect you want 1920x1080 rather than 1980x1020 May 9 at 10:57
  • Whew thanks for the catch, will do resizes using mogrify but, you're spot on! Gratis! May 9 at 11:07

2 Answers 2

4

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 at 12:31
  • 1
    … and that should obviously be: escaped_line=${line//\\/\\\\}; escaped_line=${escaped_line//\'/\\\'} :P
    – ibuprofen
    May 9 at 21:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.