2016-05-19 232 views
2

iTextSharp可以壓縮PDF文件嗎?我正在尋找可用於開發的PDF庫,以壓縮PDF文件。基本上,我有一個文件夾列表,其中包含大小從1MB到10MB的許多PDF文件,這些文件夾的數量每天都在不斷增加,因此爲了節省磁盤空間,我希望能夠在PDF文件中讀取一次它已被處理,壓縮,然後將其保存到指定的文件夾位置。iTextSharp處理PDF壓縮嗎?

如果iTextSharp不支持壓縮,是否有人對其他.NET PDF庫有建議?購買圖書館不會成爲問題。我查看了許多免費的,例如PDFSharp,這對我來說在製作PDF時非常有用,但無法呈現或壓縮它們。

有一個偉大的答案,我從克里斯·哈斯在計算器閱讀:

PdfStamper是最終使用名爲PdfStamperImp做的大部分工作的另一個類的輔助類。 PdfStamperImp派生自PdfWriter,當您使用stamper.Writer時,您實際上已經獲得了此實現類。 PdfStamper上的許多屬性也直接傳遞給實現類。所以這兩個電話實際上是做同樣的事情。

stamper.SetFullCompression();
stamper.Writer.SetFullCompression();

另一個混淆之處是SetFullCompression和CompressionLevel根本就沒有關聯。 「完全壓縮」表示在PDF 1.5中添加的一項稱爲「對象流」的功能,該功能允許將PDF對象分組在一起,以便進行更大的壓縮。實際上並沒有要求我們認爲「壓縮」實際上發生,但實際上我認爲它總會發生。 (可能一個超級簡單的文件可能會變得更大,這個啓用,不確定,不想測試。)

CompressionLevel實際上是你通常認爲的壓縮,從0到9或-1的數字意味着默認(目前等於六我認爲)。該屬性實際上是許多類最終派生自的PdfStream類的一部分。但是,此設置不會「滴流」。由於您通過GetPageContent()和SetPageContent()從另一個位置導入流,因此特定流具有與Writer的壓縮設置無關的自己的壓縮設置。實際上有第三個參數可以傳遞給SetPageContent()來設置特定的壓縮級別。

reader.SetPageContent(1, reader.GetPageContent(1), PdfStream.BEST_COMPRESSION);

https://stackoverflow.com/a/22028008/2063134

任何幫助或建議,將大大讚賞。

謝謝。

+0

您是否嘗試過@Chris'answer?的建議?它的壓縮效果不夠好嗎? – mkl

回答

3

是的,iText和iTextSharp支持壓縮。

  • 從PDF 1.0(1993)到PDF 1.1(1994),存儲在內容流中的PDF語法未被壓縮。
  • 從PDF 1.2(1996)開始,可以壓縮存儲在內容流中的PDF語法。標準過濾器是/FlateDecode。此算法與ZIP算法類似,您可以設置不同的壓縮級別(從0到9;選擇-1時將使用您的編程語言認爲是默認級別的任何級別)。
  • 從PDF 1.5(2003)開始,間接對象可以存儲在壓縮對象流中。另外,交叉引用表可以被壓縮並存儲在一個流中。在PDF 1.5之前,這是不可能的(觀衆只支持PDF 1。4及更早版本無法打開「完全壓縮」的PDF文件)。

iText支持以上所有內容,Chris的答案已經完全解答了您的問題。由於PDF從一個很長一段時間前(1994年)1.1日期,我就不會擔心不斷變化的內容流的壓縮級別,所以你可以放心地算了一下:

reader.SetPageContent(1, reader.GetPageContent(1), PdfStream.BEST_COMPRESSION); 

使用這條線不會降低文件大小很大。

使用「完全壓縮」(這會導致交叉引用表被壓縮)應該會影響具有許多間接對象的PDF的文件大小。當您使用「完全壓縮」時,最小的「Hello World」文件可能會增加文件大小。

以上所有內容對您無能爲力,因爲良好的PDF創作者已經壓縮了任何可以壓縮的內容。然而,不好的PDF創作者(或不正確地使用好的PDF創作者的人)可能包含多餘的對象。例如:有些人不知道如何使用iTextSharp將PDF作爲圖像添加到PDF中的每個頁面。由於他們的無知,他們添加圖像的次數與頁面的次數相同。在這種情況下PDF壓縮不會對你有所幫助,但是如果你通過iTextSharp的PdfSmartCopy傳遞了這樣一個「不好」的PDF,那麼PdfSmartCopy將檢測冗餘對象並重新組織文件,以便在文件中反覆重複的對象例如:每個頁面引用具有相同圖像字節的不同對象),被重用(例如:每個頁面引用與圖像字節相同的對象)。

根據您使用的iTextSharp的版本reader.RemoveUnusedObjects();也可以幫助您(最近的版本默認刪除未使用的對象)。

+0

謝謝@Bruno Lowagie,這是一個非常簡潔的迴應。我在閱讀5之前的版本是免費的,但由於可能的錯誤和不支持而不推薦。我正在考慮獲得商業許可的5.4版本。不幸的是,我們無法控制PDF生成器在哪裏創建這些文件,因此它們中可能存在冗餘。它們包含大量圖像和文本(所有這些圖像都作爲PDF中頁面上的單個圖像導出)。我會更深入地研究它,看看我是否可以將它調整到合理的文件大小。謝謝。 –

+1

此外,只是爲了拋出這個,因爲我在我的日常工作中處理這個問題,iText沒有直接處理第三種類型的「壓縮」,這是圖像的有損壓縮,通常會最大幅度地減少文件規模如果你願意犧牲質量。有一個非常高層次的示例[這裏](http://stackoverflow.com/a/8751517/231316)。基本上你使用iText來查找和提取所有圖像,執行自己的還原邏輯,然後使用iText將圖像添加回來。這是一個破壞性的改變,但在你的環境中它可能是可以接受的。 –

+1

@ChrisHaas確實如此,但這可能很危險。假設您已經掃描了以當前分辨率清晰的文本。如果讓機器決定是否降低分辨率,那麼在「壓縮」之後文本仍然可以清晰可讀的情況下,您永遠無法確定。你需要一個人來做出這個決定。 –

0

ITextSharp允許您瀏覽PDF頁面並編輯其中的對象(以及許多其他功能)。壓縮流對象(主要是圖像)可以幫助您減小整個PDF大小。

我深入研究了PDF文件的壓縮問題,主要是它內部的圖像,並用輕量級庫完成,這可以用作特定壓縮情況下的父級。

https://github.com/rock-walker/PdfCompression