2013-03-05 119 views
31

是否可以使用iTextSharp從PDF文檔中刪除不可見(或至少未顯示)的對象?使用iTextSharp刪除PDF不可見對象

更多細節:

1)我的來源是含圖片和文字(也許有些矢量繪圖)和嵌入式字體的PDF頁面。

2)有一個界面來設計多個「裁切框」。

3)我必須生成一個新的PDF,其中只包含裁剪框內的內容。其他任何東西都必須從結果文檔中刪除(實際上,我可能會接受內部一半和外部一半的內容,但這不是理想的,它不應該出現)。

我到目前爲止的解決方案:

我已經成功地開發出新創建臨時文件的解決方案,每一個都包含每種作物框的內容(使用writer.GetImportedPage和contentByte.AddTemplate一個網頁,是完全裁剪框的大小)。然後我創建最終文檔並重復該過程,使用AddTemplate方法將最終頁面中的每個「裁剪頁面」定位。

該解決方案有2個大缺點:

  • 文件的大小是[原始大小]很多次* [一批作物盒],因爲整個頁面是有,蓋章! (不可見,但它在那裏)
  • 無法看到的文本仍然可以通過在Reader中選擇全部(CTRL + A)並粘貼來訪問。

所以,我想我需要遍歷PDF對象,檢測它是否可見,並刪除它。在撰寫本文時,我正在嘗試使用pdfReader.GetPdfObject。

感謝您的幫助。

+3

由於iText提供了一個低級別的API,它允許您操作文檔中的幾乎所有內容,**這可能是**。不過**並不是說它很容易**,因爲您必須自己編寫代碼來爲頁面內容中的每個元素標識它是否可見,並且您將不得不您也可以將內容的其餘部分粘貼在一起。但是,如果您重新使用導入的頁面模板(如果要使其中的多個部分可見),則可以減少當前解決方案中生成的文檔大小。有趣的工作很多周... – mkl 2013-03-06 11:24:41

+0

嘗試使用'PdfStamper'類進行裁剪:http://itextpdf.com/examples/iia.php?id = 231 – 2013-03-31 21:33:36

+0

對於iTextSharp,我不是100%但是iPdfSharp能夠從表單渲染。這個想法是,你打開你的頁面,你正在裁剪,在一個表格內,然後只將你需要的部分渲染成一個新的文檔。您將不會製作多個副本,並且渲染(裁剪)的部分將成爲圖像。嘗試查看這是否是IText api下的選項。 – Alex 2013-05-28 08:31:03

回答

0

您是否嘗試過使用IRenderListener?通過檢查TextRenderInfo或ImageRenderInfo對象的StartPoint和EndPoint或Area,您可以選擇性地將這些元素添加到裁剪區域內的新PDF中。

1

如果您正在嘗試的PDF是模板/預定義/修正,那麼您可以通過調用RemoveField來移除該對象。

PdfReader pdfReader = new PdfReader(../Template_Path.pdf")); 
PdfStamper pdfStamperToPopulate = new PdfStamper(pdfReader, new FileStream(outputPath, FileMode.Create)); 
AcroFields pdfFormFields = pdfStamperToPopulate.AcroFields; 
pdfFormFields.RemoveField("fieldNameToBeRemoved"); 
+0

該OP不是在談論表單域。無論如何,如果有任何開始,他會在'writer.GetImportedPage'和'contentByte.AddTemplate'期間拋棄所有表單字段。 – mkl 2013-09-18 07:05:22

1
PdfReader pdfReader = new PdfReader(../Template_Path.pdf")); 
PdfStamper pdfStamperToPopulate = new PdfStamper(pdfReader, new FileStream(outputPath, FileMode.Create)); 
AcroFields pdfFormFields = pdfStamperToPopulate.AcroFields; 
pdfFormFields.RemoveField("fieldNameToBeRemoved"); 
1

是的,這是可能的。您需要將pdf頁面內容字節解析爲PdfObjects,將它們存儲到內存中,刪除未拆分的PdfObject,將Pdf內容從PdfObject構建回pdf內容字節,在通過PdfWriter導入頁面之前替換PdfReader中的頁面內容。

我建議你看看這個:從鏈接http://habjan.blogspot.com/2013/09/proof-of-concept-converting-pdf-files.html

示例實現PDF內容字節分析,從PdfObjec的建築後面,更換PdfReader網頁內容的字節...

1

下面是三種解決方案,我發現,如果它能夠幫助別人(使用iTextSharpAmyuniTracker-Software,如@Hetote在評論中說,他一直在尋找另一個庫):

使用iTextSharp的

由於answered by @martinbuberl in another question

public static void CropDocument(string file, string oldchar, string repChar) 
{ 
    int pageNumber = 1; 
    PdfReader reader = new PdfReader(file); 
    iTextSharp.text.Rectangle size = new iTextSharp.text.Rectangle(
    Globals.fX, 
    Globals.fY, 
    Globals.fWidth, 
    Globals.fHeight); 
    Document document = new Document(size); 
    PdfWriter writer = PdfWriter.GetInstance(document, 
    new FileStream(file.Replace(oldchar, repChar), 
    FileMode.Create, FileAccess.Write)); 
    document.Open(); 
    PdfContentByte cb = writer.DirectContent; 
    document.NewPage(); 
    PdfImportedPage page = writer.GetImportedPage(reader, 
    pageNumber); 
    cb.AddTemplate(page, 0, 0); 
    document.Close(); 
} 

his question另一個答案由@rafixwpt,但它不會刪除的不可見元素,它清潔頁面的區域,這會影響該頁面的其它部分:

static void textsharpie() 
{ 
    string file = "C:\\testpdf.pdf"; 
    string oldchar = "testpdf.pdf"; 
    string repChar = "test.pdf"; 
    PdfReader reader = new PdfReader(file); 
    PdfStamper stamper = new PdfStamper(reader, new FileStream(file.Replace(oldchar, repChar), FileMode.Create, FileAccess.Write)); 
    List<PdfCleanUpLocation> cleanUpLocations = new List<PdfCleanUpLocation>(); 
    cleanUpLocations.Add(new PdfCleanUpLocation(1, new iTextSharp.text.Rectangle(0f, 0f, 600f, 115f), iTextSharp.text.BaseColor.WHITE)); 
    PdfCleanUpProcessor cleaner = new PdfCleanUpProcessor(cleanUpLocations, stamper); 
    cleaner.CleanUp(); 
    stamper.Close(); 
    reader.Close(); 
} 

使用Amyuni

作爲answered by @yms in another question

IacDocument.GetObjectsInRectangle方法

GetObjectsInRectangle方法獲取指定的 中的所有對象ctangle。

然後你可以遍歷頁面中的所有對象,並刪除那些你不感興趣的:

//open a pdf document 
document.Open(testfile, ""); 
IacPage page1 = document.GetPage(1); 
Amyuni.PDFCreator.IacAttribute attribute = page1.AttributeByName("Objects"); 

// listObj is an array list of graphic objects 
System.Collections.ArrayList listobj = (System.Collections.ArrayList) attribute.Value.Cast<IacObject>();; 

// listObjToKeep is an array list of graphic objects inside a rectangle 
var listObjToKeep = document.GetObjectsInRectangle(0f, 0f, 600f, 115f, IacGetRectObjectsConstants.acGetRectObjectsIntersecting).Cast<IacObject>(); 
foreach (IacObject pdfObj in listObj.Except(listObjToKeep)) 
{ 
    // if pdfObj is not in visible inside the rectangle then call pdfObj.Delete(); 
    pdfObj.Delete(false); 
} 

正如在評論@yms表示,採用新方法IacDocument.Redact在另一種解決方案版本5.0也可用於刪除指定矩形中的所有對象,並在其位置處繪製純色矩形。

使用跟蹤,軟件編輯SDK

我沒有嘗試,但它似乎是可能的,看到這個post

+1

在Amyuni PDF Creator的情況下,在5.0版中增加了一種新方法[IacDocument.Redact](https://www.amyuni.com/WebHelp/Amyuni_PDF_Creator_for_NET/Amyuni_PDFCreator_IacDocument/Methods/IacDocument.Redact_Method.htm),它可能是在這種情況下很有幫助。 – yms 2015-10-06 16:21:18