18

I've installed Ghostscript on Windows as what I'm looking to do is compress/reduce the size of 12,000+ PDF files on a network share. This wouldn't be possible with any GUI software as it just bombs out after a while due to running out of resources, so I think command line is the way to go here.

I've read the Ghostscript documentation and different examples of compressing PDF files, but I can't seem to find anything that operates as a large batch.

Basically, I'd need to target multiple folders to recursively compress the files which will be on the network share.

Is this possible to do so with Ghostscript? If so, please advise with some command examples to help me acheive this.

Thanks!

Andre Kampling
  • 5,476
  • 2
  • 20
  • 47
BabyPython
  • 307
  • 1
  • 2
  • 6
  • I'd need to overwrite the existing PDF file with the new reduced file size, as the objective is to save space and reduce disk capacity on the share. – BabyPython Sep 13 '17 at 13:04

6 Answers6

23

With the following script you can define all directories needed in the array variable filesDir.
It will loop over all these directories and search for all pdf files in all directories including subdirectories.
For all found pdf files it will use this ghostscript command (GitHub) and output the file with name e.g. fileabc.pdf with a new name: compr_fileabc.pdf.

Edit #1:

I changed the script as requested by the comments to either write new pdf files or overwrite the input pdf file. To select between these to options change the createNewPDFs variable to 1 (new files) or 0 (overwrite).
Because ghostscript can't write to the input file the output file will be written at the users temporary path (%TEMP%) and moved to the original input file to overwite this file. It will only overwrite the input pdf file if the new file is smaller in size.
Further the ghostscript command is substituted by a variable with the same name because under Windows it can be either gswin64c (64 bit) or gswin32c (32 bit).

If the outcomming sizes are not small enough play with these ghostscript command switch: -dPDFSETTINGS=/printer, it is explained below.

Batch script:

@echo off
setlocal EnableDelayedExpansion

rem ghostscript executable name
set "ghostscript=gswin64c"

rem directories to scan for files
set "filesDir[0]=FOLDER1"
set "filesDir[1]=FOLDER2"
set "filesDir[2]=FOLDER3"

rem extension of files to be scanned
set "ext=pdf"

rem new file be creation or input file overwrite
set "createNewPDFs=0"
rem file prefix for new files (if they should be created)
set "filepre=compr_"

rem loop over all directories defined in filesDir array
for /f "tokens=2 delims==" %%d in ('set filesDir[') do (
   if exist "%%~d" (
      pushd "%%~d"
      rem loop over all files in all (sub)directories with given extension
      for /f "delims=*" %%f in ('dir "*.%ext%" /b /s /a:-d') do (
         if [%createNewPDFs%] EQU [1] (
            %ghostscript% -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/printer -dNOPAUSE -dQUIET -dBATCH -sOutputFile="%%~dpf%filepre%%%~nxf" "%%~f"
         ) else (
            %ghostscript% -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/printer -dNOPAUSE -dQUIET -dBATCH -sOutputFile="%TEMP%\%%~nxf" "%%~f"
            for %%t in ("%TEMP%\%%~nxf") do ( set "newSize=%%~zt" )
            for %%t in ("%%~f") do ( set "oldSize=%%~zt" )
            if [!newSize!] LSS [!oldSize!] (
               rem new file is smaller --> overwrite
               move /y "%TEMP%\%%~nxf" "%%~f"
            ) else (
               rem new file is greater --> delete it of the temp dir
               del "%TEMP%\%%~nxf"
            )
         )
      )
      popd
   )
)

Found GitHub ghostscript command to reduce pdf size:

This can reduce files to ~15% of their size (2.3M to 345K, in one case) with no obvious degradation of quality.

ghostscript -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/printer -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf

Other options for PDFSETTINGS:

  • /screen selects low-resolution output similar to the Acrobat Distiller "Screen Optimized" setting.
  • /ebook selects medium-resolution output similar to the Acrobat Distiller "eBook" setting.
  • /printer selects output similar to the Acrobat Distiller "Print Optimized" setting.
  • /prepress selects output similar to Acrobat Distiller "Prepress Optimized" setting.
  • /default selects output intended to be useful across a wide variety of uses, possibly at the expense of a larger output file.

Source: http://ghostscript.com/doc/current/Ps2pdf.htm


Command reference links from ss64.com:

Andre Kampling
  • 5,476
  • 2
  • 20
  • 47
  • Thanks for this script, but what if I wanted to keep the same filename and not create a new one? As I'm trying to reduce capacity on the disk. – BabyPython Sep 13 '17 at 13:07
  • Use: `set "filepre="` instead of `set "filepre=compr_"`. But first test the generated ghostscript command on one file to take care that your pdf's will not be corrupted. – Andre Kampling Sep 13 '17 at 13:11
  • Firstly, Ghostscript does not compress PDF files. It makes new ones where the appearance should be the same. Many PDF files have wasted space, which can be recovered by writing an all new file, and using image downsampling can make files still smaller, but none of this is due to compressing the PDF. It is possible (and happens sometimes) that the produced file is **larger**. You cannot write to the same filename, because Ghostscript needs to read from the original file, while writing the new file. – KenS Sep 13 '17 at 13:31
  • @KenS: Thank you! I will change my script tomorrow to meet what you have written. I will use a temporary file then and move it. – Andre Kampling Sep 13 '17 at 13:33
  • I've tested the original script and it works perfectly by creating another file. However, when using set=filepre it keeps the same filename but reduces the PDF down to 3kb. These are only test PDF's for the time being. – BabyPython Sep 13 '17 at 13:35
  • @AndreKampling Ok many thanks for your help on this. If it's not possible to do so then I may have to resort to an Adobe Acrobat action task to perform in smaller batches of 500 for example. – BabyPython Sep 13 '17 at 13:43
  • Ok perfect! Good to know it can be done then. Look forward to your response. Cheers! – BabyPython Sep 13 '17 at 14:03
  • @BabyPython: I've updated my answer/script. Now you can select between overwriting the original file or creating new. – Andre Kampling Sep 14 '17 at 07:01
  • @AndreKampling Thanks Andre. I've tested the script and it's shrinking the files down to 3KB. When opening the files, they don't display any information. Possibly because they've been reduced too much in size? – BabyPython Sep 14 '17 at 09:15
  • @AndreKampling I've checked the temp folder and there's nothing in there, but these PDF's are being shrunk very small. I've edited my post with the script that I'm applying for you to review. – BabyPython Sep 14 '17 at 09:52
  • @AndreKampling Ok so we want the line to be: echo set "ghostscript=gswin64c" ? – BabyPython Sep 14 '17 at 10:06
  • @AndreKampling My mistake. The script wasn't updated in the correct location. However, now when running it I get the following: `set"ghostscript=gswin64c"' is not recognized as an internal or external command`. It seems like the working directory for GS needs to be specified perhaps? – BabyPython Sep 14 '17 at 10:24
  • @AndreKampling Well I have two commands within `C:\Program Files\gs\gs9.21\bin` which are **gswin64** and **gswin64c**, but it seems that I have to be in this working directory to run the application. – BabyPython Sep 14 '17 at 11:45
  • @AndreKampling I adjusted the script previously to change directory before running GS. I'll test and try again. Thanks. – BabyPython Sep 14 '17 at 12:01
  • 2
    @BabyPython: I put effort in this. It would be nice if you honor that by answering if you get more errors or if it is working now. Further let us delete us our previous made comments. Generally you would discuss in chat but as I said that works if a user has at least 20 reputation points. – Andre Kampling Sep 19 '17 at 06:43
  • @AndreKampling I'd suggest having patience. I'm on here when I can get on here and do not spend every second on here so do not speak to me about "honouring" anything. That's my decicion and not yours. I would have got on here eventually to provide my feedback. The script does not work effecitvely for the purpose that I need it as it reduces the file size to the point where they don't open. I'll close this post as "resolved! – BabyPython Sep 21 '17 at 10:47
  • 4
    Note that by default Ghostscript removes hyperlinks from PDFs. To preserve links, include the flag `-dPrinted=false`. – catleeball Jul 08 '19 at 04:42
  • @AndreKampling.i tried that bash script but for all the commands like `/f` `rem` etc i am getting some errors.Eg `compress.sh: line 21: syntax error near unexpected token `"tokens=2 delims=="' compress.sh: line 21: `for /f "tokens=2 delims==" %%d in ('set filesDir[') do (' ` – User09111993 Apr 02 '20 at 07:10
  • 1
    @User09111993 It's not a Linux Shell script, it's a Windows Batch file. – Andre Kampling Apr 02 '20 at 07:14
11

I don't know if anyone need it, but here's my command to highly compress PDF files with no degradation of quality. I've found it by method of many trials and errors an it's greatly reduce PDF files size. P.S. Sorry for posting not in the above thread, but I don't enough reputation for it as a newcomer.

%ghostscript% -q -dNOPAUSE -dBATCH -dSAFER -dSimulateOverprint=true -sDEVICE=pdfwrite -dPDFSETTINGS=/ebook -dEmbedAllFonts=true -dSubsetFonts=true -dAutoRotatePages=/None -dColorImageDownsampleType=/Bicubic -dColorImageResolution=150 -dGrayImageDownsampleType=/Bicubic -dGrayImageResolution=150 -dMonoImageDownsampleType=/Bicubic -dMonoImageResolution=150 -sOutputFile=output.pdf input.pdf
Alexey Pavlunin
  • 119
  • 1
  • 3
  • 1
    Excellent! This answer should be highly appreciable. I have tried with 79.6MB pdf file which is greatly reduced to 7.1MB. – pown Jun 16 '21 at 14:22
  • 1
    `-dSimulateOverprint={true|false}` is no longer supported. Use `-dOverPrint=/simulate` instead. Great answer btw! – Sajith Sageer Aug 26 '21 at 11:09
1

I was facing the same issue this helped me. converted 15 MB pdf into 400kb

gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.2 -r200 -dPrinted=false -dNOPAUSE -dQUIET -dBATCH -sOutputFile=c12_{filename} {filename} 
1

[Using Mac] I needed to reduce the size of multiple pdf files at the same time.

So, I used Ghostscript and a bash script to do this.

  1. Install via brew
$ brew install ghostscript
  1. Place all your pdf files into a folder.
  2. Create inside the same folder a new empty directory named output/
  3. In the same folder, create a bash script named script.sh for example.
  4. Run the script using sh script.sh
#!/bin/bash

# Get a list of all .pdf files in the current directory
files=$(ls *.pdf)

# Loop over the list of files
for file in $files
do
  echo "Processing file: $file"

  # Run the GS script for each file
  gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.2 -r200 -dPrinted=false -dNOPAUSE -dQUIET -dBATCH -sOutputFile=./output/"$file" "$file" &

  # Wait for the previous command to finish before starting the next one
  wait $!

  echo "Finished processing file: $file"
done

echo "All .pdf files have been processed"
luispa
  • 133
  • 3
  • 7
0

nothing here worked with latest gs, so I ended up with

gswin64c.exe -dPDFSETTINGS#/ebook -dPDFX -dBATCH -dNOPAUSE -sColorConversionStrategy=CMYK -sDEVICE=pdfwrite -sOutputFile="output.pdf" "input.pdf"

And with autosize form jpg and rotation 90 degrees clockwise

gswin64c -dORIENT1=false -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=C:\Users\username\Desktop\somepdffile.pdf -c "<</Orientation 3>> setpagedevice" -f "C:\Program Files\gs\gs9.19\lib\viewjpeg.ps" -c "(C:\\Users\\username\\Desktop\\somejpgfile.JPG) << /PageSize 2 index viewJPEGgetsize 2 array astore  >> setpagedevice viewJPEG"

/Orientation 3 controls rotation angle

0

I did notice that under many topics like this one, users are looking for an easy way to make PDF-files smaller for delivery over the net. E.g. Windows 10 inbuilt PDF-writer has no means of compressing PDF-files.

That's why I want to share here my final version of an automated Ghostscript PDF conversion batch file for Windows 64-bit. This batch file converts a Large PDF file automatically to a smaller version when a user drags and drops the file on top of this batch file in a Windows folder. Note! - this BATCH file and the Large PDF file must be located in the same folder, and a correct version (32/64-bit) Ghostscript must be installed on Windows before using this. Note also that this batch saves the original large PDF with a name that ends with "_original.pdf" when used once on the same file. If the user keeps converting the same file repeatedly, the original file will be replaced by the smaller version.

@echo off
rem
rem === This part separates the filename and folder names to two different variables and replaces empty spaces in filename with underlines ===
set filename=%1
set filename=%filename: =_%
for %%A in ("%filename%") do (
set Folder=%%~dpA
set Name=%%~nA )
echo.Folder is: %Folder%
echo.Name is: %Name%
rem 
rem === Copy the original file to - Name_original.pdf - removing the space from the end of - Name - variable ===
copy %1 "%Name: =_%original.pdf"
rem
rem === Copy the original file to a temporary file for Ghostscript to use ===
copy %1 oldTempFile.pdf
rem
rem === Run Ghostscript to create much smaller size PDF from your original and replace the drag and dropped - Name.pdf - file with it ==
gswin64.exe -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dBATCH -dQUIET -dDownsampleColorImages=true -dColorImageResolution=200 -dColorImageDownsampleType=/Bicubic -sOutputFile=%1 oldTempFile.pdf
rem
rem == Remove the temporary file after use ===
del oldTempFile.pdf
Supernuija
  • 19
  • 2