簡體   English   中英

使用 PHP 的 exec (Laravel on Docker) 壓縮 Ghostscript PDF 文件

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

需要做什么:

用戶必須能夠上傳 PDF,然后將文件上傳到 Amazon S3 存儲桶,然后文件應該被壓縮。

當前環境:

  • Laravel 應用程序(安裝在 Docker 上)( php:7.4-fpm-alpine3.11GPL Ghostscript 9.50Laravel Framework 5.8.37
  • 用於保存文檔的 Amazon S3 存儲桶
  • 腳本位於 shell 文件中,該文件可執行並添加到 /usr/local/bin 作為shrink
  • Shell 沒有明確添加到 Docker 容器中,應該是這樣嗎?

當前流量:

  1. 用戶上傳文件
  2. 文件上傳到S3
  3. Laravel 然后將文件下載到本地臨時文件夾
  4. 然后運行 ​​Ghostscript 以壓縮所述文件(此腳本
  5. 壓縮文件上傳回 S3

問題:

該文件已找到並正在壓縮,但輸出為空白(1 頁,白色)pdf 文件。

Dockerfile:

# 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執行它的工作並成功壓縮圖像。

我試過什么:

  • (Local) 不使用Docker成功壓縮文件,使用php artisan serve啟動Laravel app;
  • (本地)使用docker exec -it <container_id> shrink in.pdf out.pdf成功地使用 Docker 壓縮文件;
  • (本地)使用docker exec -it <container_id> /bin/bash在它的外殼中使用 Docker 成功壓縮文件;
  • (本地)我的同事在本地做了同樣的事情,響應也是空白的pdf

好的,所以問題出在這里:

$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 仍將從輸入文件中讀取。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM