使用iTextSharp删除PDF不可见对象

时间:2013-03-05 18:42:01

标签: c# pdf itextsharp

是否可以使用iTextSharp从PDF文档中删除不可见(或至少不显示)的对象?

更多详情:

1)我的来源是一个PDF页面,其中包含图像和文字(可能是一些矢量图)和嵌入字体。

2)有一个设计多个“裁剪框”的界面。

3)我必须生成一个新的PDF,其中只包含裁剪框内的内容。必须从结果文件中删除任何其他内容(事实上,我可以接受内部一半和一半外部的内容,但这不是理想的内容,无论如何都不应该出现。)

到目前为止我的解决方案:

我已经成功开发了一个创建新临时文档的解决方案,每个文档都包含每个裁剪框的内容(使用writer.GetImportedPage和contentByte.AddTemplate到一个与裁剪框大小完全相同的页面)。然后我创建最终文档并重复该过程,使用AddTemplate方法将每个“裁剪页面”放在最后一页中。

此解决方案有两大缺点:

  • 文件的大小是[原始尺寸] * [裁剪框数],因为整个页面都在那里,标记了很多次! (看不见,但它就在那里)
  • 仍然可以通过在Reader中选择所有(CTRL + A)并粘贴来访问不可见文本。

所以,我认为我需要遍历PDF对象,检测它是否可见,然后删除它。在撰写本文时,我正在尝试使用pdfReader.GetPdfObject。

感谢您的帮助。

5 个答案:

答案 0 :(得分: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");

答案 1 :(得分: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");

答案 2 :(得分: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页面内容字节......

答案 3 :(得分: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方法获取所有对象   指定的矩形。

然后,您可以迭代页面中的所有对象并删除您不感兴趣的对象:

//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在评论中所说,使用5.0版中新方法IacDocument.Redact的另一种解决方案也可用于删除指定矩形中的所有对象,并在其位置绘制纯色矩形。 / p>

使用Tracker-Software Editor SDK

我没有尝试,但似乎有可能,请参阅此post

答案 4 :(得分:0)

您是否尝试过使用IRenderListener?您可以通过检查TextRenderInfo或ImageRenderInfo对象的StartPoint和EndPoint或Area,有选择地仅将这些元素添加到属于裁剪区域的新pdf中。

相关问题