Ghostscript PDF批量压缩

18
我在Windows上安装了Ghostscript,因为我想要压缩/减小网络共享中12,000多个PDF文件的大小。任何GUI软件都无法完成此任务,因为它会在一段时间后耗尽资源而崩溃,所以我认为命令行是解决方案。
我已经阅读过Ghostscript文档和不同的压缩PDF文件示例,但好像找不到适用于大规模批处理的东西。
基本上,我需要递归地压缩位于网络共享中的多个文件夹。
是否可以使用Ghostscript来实现这一点?如果是,请给出一些命令示例来帮助我完成这个任务。
谢谢!

我需要用新的减小文件尺寸的文件覆盖现有的 PDF 文件,因为目标是节省空间和减少共享磁盘容量。 - BabyPython
6个回答

23
使用以下脚本,您可以在数组变量filesDir中定义所有所需的目录。
它将循环遍历所有这些目录,并在包括子目录的所有目录中搜索所有pdf文件。
对于所有找到的pdf文件,它将使用此ghostscript命令(GitHub)并以新名称输出文件,例如fileabc.pdf的新名称为:compr_fileabc.pdf编辑#1: 根据评论的要求,我更改了脚本以编写新的pdf文件或覆盖输入pdf文件。要在这两个选项之间选择,请将createNewPDFs变量更改为1(新文件)或0(覆盖)。
由于ghostscript无法写入输入文件,因此输出文件将写入用户临时路径(%TEMP%)并移动到原始输入文件以覆盖此文件。只有在新文件大小较小时,它才会覆盖输入pdf文件。
此外,ghostscript命令被替换为具有相同名称的变量,因为在Windows下它可以是gswin64c(64位)或gswin32c(32位)。
如果出站大小不够小,请尝试使用这些ghostscript命令开关:-dPDFSETTINGS=/printer,下面将对其进行解释。 批处理脚本:
@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
   )
)

发现了GitHub上的Ghostscript命令,可以降低pdf文件的大小:


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


来自ss64.com的命令参考链接:

  • set - 设置环境变量。
  • DelayedExpansion - 启用延迟变量扩展。
  • for /f - 从文件中读取行。
  • dir - 列出目录中的文件和子目录。
  • if - 条件语句。
  • pushd - 压入并更改当前目录。
  • popd - 弹出当前目录,并返回先前目录。
  • rem - 注释。

首先,Ghostscript不会压缩PDF文件。它会创建一个外观相同的新文件。许多PDF文件存在浪费空间,可以通过编写全新文件来恢复这些空间,并且使用图像降采样可以使文件更小,但这都与压缩PDF无关。有时候生成的文件可能会更大。您不能写入相同的文件名,因为Ghostscript需要从原始文件中读取,同时编写新文件。 - KenS
@AndreKampling 好的,非常感谢您在此事上的帮助。如果无法这样做,那么我可能不得不采取Adobe Acrobat操作任务来分批处理,例如每500个一组。 - BabyPython
2
@BabyPython:我在这方面付出了努力。如果您遇到更多错误或现在已经解决了问题,如果您能回答一下,那将是很好的。此外,让我们删除之前发表的评论。通常情况下,您可以在聊天中讨论,但正如我所说,这仅适用于至少拥有20个声望点的用户。 - Andre Kampling
4
请注意,默认情况下Ghostscript会从PDF文件中删除超链接。如果要保留链接,请加入标志“-dPrinted=false”。 - catleeball
1
@User09111993 这不是Linux Shell脚本,而是Windows批处理文件。 - Andre Kampling
显示剩余14条评论

12

我不知道是否有人需要,但这是我的命令,可以高度压缩 PDF 文件而不会降低质量。通过多次尝试和错误的方法,我找到了它,可以大大减小PDF文件的大小。 P.S. 抱歉没有在上面的线程中发布,但作为新手,我没有足够的声望。

%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

1
太好了!这个答案应该会受到高度赞赏。我尝试了一个大小为79.6MB的PDF文件,它被大大压缩到了7.1MB。 - pown
1
“-dSimulateOverprint={true|false}”不再受支持。请改用“-dOverPrint=/simulate”。顺便说一句,回答很棒! - Sajith Sageer

1

我遇到了同样的问题,这个帮助了我。将15 MB的PDF转换成了400kb。

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

1
[使用Mac] 我需要同时减小多个pdf文件的大小。
因此,我使用了Ghostscript和一个bash脚本来完成这个任务。
  1. 通过brew安装
$ brew install ghostscript
  1. 将所有的pdf文件放入一个文件夹中。
  2. 在同一文件夹中创建一个名为output/的新空目录。
  3. 在同一文件夹中,创建一个名为script.sh的bash脚本。
  4. 使用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"

0

这里的所有内容都无法与最新的gs一起使用,所以我最终选择了

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

并且使用自适应大小形式的jpg和顺时针旋转90度

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"

/方向3控制旋转角度


0

我注意到在许多类似这样的主题下,用户都在寻找一种简单的方法来缩小PDF文件以便通过网络传输。例如,Windows 10内置的PDF编写器没有压缩PDF文件的手段。

这就是为什么我想在这里分享我的最终版本的自动Ghostscript PDF转换批处理文件,适用于Windows 64位。当用户将大型PDF文件拖放到Windows文件夹中的此批处理文件上方时,此批处理文件会自动将其转换为较小的版本。请注意!-此批处理文件和大型PDF文件必须位于同一文件夹中,并且在使用之前必须在Windows上安装正确版本(32/64位)的Ghostscript。还要注意,当对同一文件使用一次后,此批处理将使用以“_original.pdf”结尾的名称保存原始大型PDF。如果用户不断转换相同的文件,则原始文件将被较小的版本替换。

@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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接