23

I want to write a Bash script to convert every .pdf file in the current directory into a .png file.

For example:

$ls .
a.pdf b.pdf

$./pdf2png.sh Converting pdfs to pngs a.pdf -> a.png b.pdf -> b.png

This is my best attempt:

#!/bin/bash
convert -verbose -density 500 -resize '800' a.pdf a.png
convert -verbose -density 500 -resize '800' b.pdf b.png
Toby Speight
  • 8,678

4 Answers4

23

If you have really strange names, ones that contain newlines or backslashes and the like, you could do something like this:

find . -type f -name '*.pdf' -print0 |
  while IFS= read -r -d '' file
    do convert -verbose -density 500 -resize 800 "${file}" "${file%.*}.png"
  done

That should be able to deal with just about anything you throw at it.

Tricks used:

  • find ... -print0 : causes find to print its results separated by the null character, let's us deal with newlines.
  • IFS= : this will disable word splitting, needed to deal with white space.
  • read -r: disables interpreting of backslash escape characters, to deal with files that contain backslashes.
  • read -d '': sets the record delimiter to the null character, to deal with find's output and correctly handle file names with newline characters.
  • ${file%.*}.png : uses the shell's inbuilt string manipulation abilities to remove the extension.
terdon
  • 242,166
  • Both answers are good but I accepted this one because it comes with an explanation of the tricks used. – I Like to Code Mar 25 '14 at 14:13
  • 2
    Or do it portably (POSIX) and still handle any special characters: find . -type f -name '*.pdf' -exec sh -c 'for f do convert -verbose -density 500 -resize 800 "$f" "${f%.pdf}.png"; done' find-sh {} + See https://unix.stackexchange.com/a/321753/135943 for explanation and background. – Wildcard Jun 26 '17 at 22:01
  • 1
    @Wildcard the only non-posix thing here is find's -printf, so all you'd need for portability is to replace it with -exec printf '%s\0' {} +. – terdon Jun 26 '17 at 22:21
17

You can use bash for loop as follows:

#!/bin/bash
for pdfile in *.pdf ; do
  convert -verbose -density 500 -resize '800' "${pdfile}" "${pdfile%.*}".png
done
Ketan
  • 9,226
9

You could use mogrify to batch convert & resize all .pdfs in the current directory:

mogrify -verbose -density 500 -resize 800 -format png ./*.pdf

When using a different format (in this case -format png) the original .pdfs are left untouched, the output files having the same name except for the extension which will be changed to the one specified by format.

don_crissti
  • 82,805
2

If you're not restricted to using bash, then you could use a python script to convert all of the .pdf files in the current directory to high-resolution .png images. It could be modified for other input/output image types, or to use different arguments for convert.

#! /usr/bin/env python

import os

def main():
    dir_list = os.listdir('.')
    for full_file_name in dir_list:
        base_name, extension = os.path.splitext(full_file_name)
        if extension == '.pdf': # then .pdf file --> convert to image!
            cmd_str = ' '.join(['convert',
                                '-density 400',
                                full_file_name,
                                base_name + '.png'])
            print(cmd_str)  # echo command to terminal
            os.system(cmd_str)  # execute command

if __name__ == '__main__':
    main()
MattKelly
  • 121