14

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
16

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.
  • 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
  • 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 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
11

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
5

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.

1

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()

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.