2015-04-23 95 views
0

壓縮PDF爲了將它們存儲到數據庫中之前壓縮上傳PDF格式的文件,我有這樣的代碼在mojolicious控制器:忽略臨時文件時使用Ghostscript

# if > 100k compress with gs 
    my $pdf; 
    if ($size > 100_000) { 
     # create tmp-file to be read by gs 
     my $tmp_fn = '/tmp/badb_pdf_input.pdf'; 
     $file->move_to("$tmp_fn"); 

     use Capture::Tiny 'capture'; 
     my ($stdout, $stderr, $exit) = capture { 
      my $cmd = '/usr/local/bin/gs'; 
      my @args = (qw(-sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile=-)) ; 
      push @args, $tmp_fn; 
      system($cmd, @args) == 0 
       or die "system @args failed: $!" 
     }; 
     die "ERROR compressing pdf: $stderr" if $stderr; 
     unlink $tmp_fn; 
     $pdf = $stdout; 
    } else { 
     $pdf = $file->slurp; 
    } 

有誰知道的方式,以避免輸入的臨時文件(/tmp/badb_pdf_input.pdf)?

回答

1

確定首先你不是'壓縮PDF文件'。您正在做的是解釋原始PDF文件,創建一系列標記操作,然後從這些標記操作中創建一個新的PDF文件。這不是同一件事,它是重要的差異。

例如,其然後可以被顏色轉換數據,或降低圖像的分辨率(當選擇/電子書兩者均可能發生)的事情之一。如果你只是'壓縮'文件,你不會改變數據,所以這些改變是不可能的。

但是,您也可能會丟失信息。 Ghostscript的pdfwrite設備的唯一目標目標是視覺外觀應該保持不變(只要是合理的,如果您更改分辨率等)。元數據可能不會保留。事實上,pdfwrite設備不保留某些元數據(例如嵌入式Illustrator文件)的事實是它可以生成較小PDF文件的部分原因。

我KN OW一無所知「mojolicious」,但你似乎是試圖通過標準輸入數據發送到Ghostscript的閱讀和生成的PDF從標準輸出回來?

如果是這樣,那麼你實際上將創建多個臨時文件。一般來說,不能從stdin處理PDF文件,因爲PDF格式需要隨機訪問文件。因此,如果您將PDF文件傳輸到標準輸入,Ghostscript會執行的第一件事是創建一個臨時文件,並將標準輸入的PDF文件輸入到其中。然後它可以解釋文件。另外pdfwrite將創建許多臨時文件,因爲它會創建輸出。

你「可以」選擇標準輸出爲目的地的PDF文件,但.....

正如我所提到的PDF格式是隨機訪問,其通常的做法是寫文件的部分,爲尚未知道的位留下空間,然後倒帶文件並在您做時填充它們。顯然這不適用於不可查找的流。目前,pdfwrite設備僅在創建線性化(針對快速Web查看優化)PDF文件時執行此操作,但我不保證將來版本的pdfwrite不需要在輸出文件中查找。

那麼簡單的答案是,你可以設置OUTPUTFILE進行標準輸出,但不保證其正常工作。

+0

感謝您花時間解釋基礎!因此,將一些PDF編入ghostscript當然是不可能的。 (例如'cat mayflle.pdf | ghostscript ...'是不行的,由於PDF文件的性質,它將永遠不會工作) – lanti

+0

它可以工作,但是GS在幕後會做的事情是將stdin輸入到一個臨時文件在磁盤上,因爲正如你所說,這是PDF文件的性質,你必須在裏面尋找。 – KenS

0

如果上傳PDF有大小乞丐超過256 KB(默認情況下,看到max_memory_size),那麼你並不需要保存臨時文件,因爲它已經保存。

Here是最小的例子,如何讓路徑到您的文件。