使用 PHP 的 exec 压缩 Ghostscript PDF 文件(Laravel on Docker)

Ghostscript PDF file compression using PHP's exec (Laravel on Docker)

需要做的事情:

用户必须能够上传 PDF,然后将文件上传到 Amazon S3 存储桶,然后应压缩文件。

当前环境:

当前流量:

  1. 用户上传文件
  2. 文件已上传到 S3
  3. Laravel 然后将文件下载到本地临时文件夹
  4. Ghostscript 然后 运行 压缩所述文件(这个 script
  5. 压缩文件上传回 S3

问题:

文件已找到并正在压缩,但输出为空白(1 页,白色)pdf 文件。

Docker文件:

# Add compression shell script to global executables
COPY .docker/config/shrink.sh /usr/local/bin/shrink
RUN chmod u+x /usr/local/bin/shrink
RUN chown nobody.nobody /usr/local/bin/shrink

nobody 是用户 PHP 是 运行。

PHP 应该压缩文件的函数:

public function optimizeFile($file_path)
    {
        // Copy file from default disk to temp disk
        Storage::disk('temp')->put($file_path, Storage::get($file_path));

        $fullTempFilePath = Storage::disk('temp')->path($file_path);

        if (Storage::mimeType($file_path) == 'application/pdf') {
            $output = shell_exec("shrink " . $fullTempFilePath . " " . $fullTempFilePath);
            if ($output != null) {
                Log::error($output);
            }
        } else {
            ImageOptimizer::optimize($fullTempFilePath);
        }

        // Write the compressed file back to default disk
        Storage::put($file_path, Storage::disk('temp')->get($file_path));

        // Delete temp file
        Storage::disk('temp')->delete($file_path);
    }

如果文件不是 PDF,ImageOptimizer 会完成它的工作并成功压缩图像。

我尝试了什么:

好的,所以问题就在这里:

$output = shell_exec("shrink " . $fullTempFilePath . " " . $fullTempFilePath);

如果输入和输出文件相同,Ghostscript PDF 压缩无法按预期工作。解决方案:

$output = shell_exec("shrink " . $fullTempFilePath  . $fullTempFilePath . "-compressed ");
shell_exec("mv " . $fullTempFilePath . "-compressed " . $fullTempFilePath);

好的,第一点; Ghostscript(更准确地说是 Ghostscript pdfwrite 设备)不会缩小 PDF 文件。 VectorDevices.htm 中概述中的文档中描述了实际过程。我建议您阅读它。

其次,输入和输出文件不能使用相同的名称。当 pdfwrite 设备想要写入输出文件时,Ghostscript 仍会从输入文件中读取。