37

If I have a plain text file, how can I convert it to an image file through the command line? (and preserve the layout of the ASCII art in it)

6
  • I would start looking for a automatic way to render text with a monospace font (gimp or LaTeX might be the way to go)
    – RSFalcon7
    Commented Jun 23, 2014 at 19:05
  • This is an ugly solution, but why don't just cat it and take a screenshot?
    – psimon
    Commented Jun 23, 2014 at 19:09
  • That would be too ugly, and a screenshot would include additional information, like the prompt. Commented Jun 23, 2014 at 19:12
  • If only the prompt is the problem, try this: clear && cat file. But yes, it's ugly.
    – psimon
    Commented Jun 23, 2014 at 19:13
  • no that would still show my user name... And unless I find a way of making a screenshot through the command line, it won't be acceptable. Commented Jun 23, 2014 at 19:16

4 Answers 4

39

imagemagick is your friend here. Something similar to the following may help you:-

convert -size 360x360 xc:white -font "FreeMono" -pointsize 12 -fill black -draw @ascii.txt image.png

where ascii.txt is your ascii-art file:-

text 15,15 "                 .88888888:. 
                88888888.88888. 
              .8888888888888888. 
              888888888888888888 
              88' _`88'_  `88888 
              88 88 88 88  88888 
              88_88_::_88_:88888 
              88:::,::,:::::8888 
              88`:::::::::'`8888 
             .88  `::::'    8:88. 
            8888            `8:888. 
          .8888'             `888888. 
          .8888:..  .::.  ...:'8888888:. 
        .8888.'     :'     `'::`88:88888 
       .8888        '         `.888:8888. 
      888:8         .           888:88888 
    .888:88        .:           888:88888: 
    8888888.       ::           88:888888 
    `.::.888.      ::          .88888888 
   .::::::.888.    ::         :::`8888'.:. 
  ::::::::::.888   '         .:::::::::::: 
  ::::::::::::.8    '      .:8::::::::::::. 
 .::::::::::::::.        .:888::::::::::::: 
 :::::::::::::::88:.__..:88888:::::::::::' 
  `'.:::::::::::88888888888.88:::::::::' 
        `':::_:' -- '' -'-' `':_::::'`  
    "

with text 15,15 added as the first line of text (the 15,15 is a positional offset). Also, make sure that the actual text to be converted is enclosed in quotes. Single or double quotes will do, but make sure they're not used as part of your ascii-art as it will confuse matters.

The font you choose should be a monospaced font, otherwise the text won't align.

This produces:-

enter image description here

4
  • 1
    Do you have a hint on how to get a list of valid font names? While Free Mono seems to be installed on my system, imagemagick does not recognize it.
    – Raphael
    Commented Sep 28, 2015 at 21:47
  • 3
    @Raphael: You can get a list of currently-available fonts from any ImageMagick command (including convert) using the -list option. So e.g. convert -list font would show you all of the possible arguments to -font.
    – FeRD
    Commented Dec 14, 2015 at 18:37
  • You could also install this program by using sudo yum install ImageMagick. Commented Jun 14, 2017 at 18:14
  • @R.Ketkaew That command is valid for someone running Fedora 21 or lower, or some revisions of RHEL (not even sure if the latest is still using yum). On Fedora 22+ the install command is sudo dnf install ImageMagick, and on most other popular Linux distros it'll be some sudo apt-get install ... command. Regardless, the information above does indeed assume that ImageMagick is installed on the system in question.
    – FeRD
    Commented Jun 22, 2017 at 1:41
21

I find ImageMagick's -annotate operator to be a bit more convenient than the -draw method garethTheRed suggested, for the simple reason that it doesn't require modification of the input file. It's not as powerful as -draw, but for wholesale dumping of a text file's contents into an image it serves just fine.

convert -size 360x360 xc:white -font "FreeMono" -pointsize 12 -fill black \
-annotate +15+15 "@ascii.txt" image.png

will output a rendered version of the given file contents, but without having to modify your "ascii.txt" file to contain the text 15x15 part of the -draw primitive.

Specifying Arguments

The argument to -font can be any supported font name, if FreeMono isn't available (or simply isn't desired). A list of the fonts available to any ImageMagick command can be obtained using the -list operator, so convert -list font will display all of the possible arguments to -font.

The arguments to -annotate (how far to shift the rendered text from the edge of the canvas) consist of horizontal and vertical pixel offsets (respectively). The first offset (horizontal x-shift) can be any positive integer, but needn't be greater than a few pixels. The second offset (vertical y-shift) must be at least equal to the point size of the font chosen (the argument to -pointsize), because ImageMagick will place the baseline of the font at the given offset. So if you don't shift the font down at least pointsize pixels, the top of the first line will be cut off.

I recommend going over by several pixels at least, so if you're using -pointsize 64 then you should pair that with something like -annotate +15+80. (There's no reason to increase the horizontal offset with larger font sizes, it has no relationship to the text dimensions.)

Needing to guess the necessary dimensions of the output image can also be tedious. I usually just pick excessive values, then take advantage of ImageMagick's -trim and -border to autocrop the result. The following command:

convert -size 1000x2000 xc:white -font "FreeMono" -pointsize 12 -fill black \
-annotate +15+15 "@ascii.txt" -trim -bordercolor "#FFF" -border 10 +repage image.png

will render into a 1000x2000 box, then trim off the excess white space except for a 10-pixel border all the way around the text. The +repage at the very end prevents the output PNG being created with an image offset, which would otherwise cause GIMP to pop up a dialog on load asking whether it should apply the offset.

(Obviously, 1000x2000 is excessive for small text files, and for longer ones at least the vertical dimension may need to be increased. It's simpler to overestimate, though, as the only cost is convert consuming slightly more CPU and memory while processing.)

Preprocessing Input

If your text file isn't already formatted the way you need in order to render it (say, if it uses very long lines) then you may have to reformat it before handing it to convert. ImageMagick won't wrap the text, so each line of text will extend its full length horizontally. Fortunately, it's possible to run the file through any command-line formatters you'd like, then pipe the processed text into convert instead of reading directly from the file:

fmt < ascii.txt | convert -size 1000x2000 xc:white -font "DejaVu-Sans-Condensed" \
-pointsize 24 -fill black -annotate +15+30 "@-" -trim -bordercolor "#FFF" \
-border 10 +repage image.png

That'll render the contents of ascii.txt in 24-point DejaVu Sans Condensed, after it's been processed by the fmt command, which in its default mode of operation will reformat its input by word-wrapping to a width of 75 columns. (Unless there are long continuous strings longer than 75 characters, like URLs, in which case they'll extend over.)

Once fmt has reformatted the text, it'll be passed to convert which will then render the piped fmt output, same as if it was reading the file directly. (Specifying a filename of - is a fairly common UNIX shell shorthand for "read from standard input, instead of any named disk file", and ImageMagick's tools follow that convention.)

9
  • 1
    The y component of annotate argument should be bigger than pointsize to be sure everything appears: convert -size 1000x2000 xc:white -font "FreeMono" -pointsize 123 -fill black \ -annotate +0+123 "@ascii.txt" -trim -bordercolor "#FFF" -border 10 +repage image.png where 123 is the desired size. Also, you can use convert -list font to find out which fonts are supported ("FreeMono" isn't universally supported). Commented Mar 3, 2018 at 22:23
  • @AlecJacobson That's a good point, about the Y value, since -annotate positions from the font baseline. +15+15 is enough for 12-point, but larger fonts might not fit. I personally wouldn't set the X value to 0, or the Y value to exactly the point size, though, because IM will antialias fonts by default. So I can't say for certain, but it feels like a gamble pressing the text right up against the edge of the bounding box. I figure better to leave a little extra on the top and left, since you're going to be automatically trimming it anyway. Two sides or four, no difference. IMHO.
    – FeRD
    Commented Mar 3, 2018 at 22:36
  • 1
    @CiroSantilli新疆改造中心法轮功六四事件 Hmm, good question. My IM7 install doesn't have any policies set in /etc/ImageMagick-7/policy.txt that interfere with any of these convert forms. Do you know what policy is blocking the convert, and why it's set? (Also, grasping at straws: Does the piped fmt ... form of the command work, by any chance? If so, you could just replace fmt with cat, and get the same result as the @ascii.txt version.)
    – FeRD
    Commented Oct 10, 2019 at 23:24
  • 1
    @CiroSantilli新疆改造中心法轮功六四事件 Oh, one more question: You specified "failed... with the tux without the ugly metadata". Does that mean that convert succeeds when you use @garethTheRed's -draw form and insert the positioning commands into the ascii.txt file? It'd be pretty bizarre if that's the case, seems to me, since I'm having trouble imagining what security concerns there would be with -annotate that wouldn't also apply to -draw, when working off the contents of an imported text file.
    – FeRD
    Commented Oct 10, 2019 at 23:29
  • 1
    I hadn't even tried Gareth's answer because of the ugly metadata, but that did work now. My /etc/ImageMagick-6/policy.xml contains <policy domain="path" rights="none" pattern="@*"/> so I'm guessing that's the one. stdin also doesn't work, presumably because it also has the @- pattern in it. For the desperate, "$(cat ascii.txt)" works if it doesn't blow up CLI length. Commented Oct 21, 2019 at 8:06
10

You could use openoffice (libreoffice) to do it.

soffice --convert-to jpg "Textfile.doc"

it works with text files too.

6
  • That... is awesome! I had no idea OpenOffice could convert to JPG... or PNG, which I just tried; probably other formats as well. (Doesn't help that there's no mention or even hint of this in the --help output.) Only wrinkle, if the text is longer than a page, it looks like you only get the first page. (If there's a way to tell it to output other pages or multiple files, it's not immediately obvious to me. Passing --outdir makes no difference.) But for short bits of text, it works EXTREMELY well, and even auto-wraps. Nice!
    – FeRD
    Commented Mar 3, 2018 at 23:20
  • This produces a fixed sized page with potentially tiny text on it if the text is small. Commented Oct 10, 2019 at 9:45
  • 1
    @CiroSantilli新疆改造中心法轮功六四事件 Fixed-size page, true, but that's where ImageMagick's auto-cropping comes in handy again: soffice --convert-to jpg ascii.txt && mogrify -trim -bordercolor "#FFF" -border 10 +repage ascii.jpg
    – FeRD
    Commented Oct 22, 2019 at 20:43
  • 3
    I don't want to change the meaning of your answer, but I highly suggest editing it to --convert-to png instead. It's not only lossless (no ugly JPEG artifacts), but for something simple like text, the file size will probably be smaller for PNG than for even a moderate quality JPG.
    – mwfearnley
    Commented May 12, 2020 at 13:13
  • 2
    Yeah, @mwfearnley is right, PNG is definitely a better choice. For the ASCII-art Tux we've been using as a sample in the answers here, the difference between JPG and PNG was 34K vs 19K ­— and that's before I trimmed the margins. Once it was trimmed, the PNG is only 3.3K to the JPG's 30K... and the PNG is clearer, too.
    – FeRD
    Commented Jun 11, 2020 at 18:13
9

A simple solution is to use pango-view provided by Pango, a text rendering library used in GTK you likely already have installed:

pango-view --font=mono -qo image.png file

You can create SVGs too!

pango-view --font=mono -qo image.svg file

pango-view has many customization and layout option, consult its man page.

You must log in to answer this question.

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