删除PDF不可见的对象与iTextSharp
本文关键字:对象 iTextSharp PDF 删除 | 更新日期: 2023-09-27 18:02:29
是否可以使用iTextSharp从PDF文档中删除不可见(或至少不显示)的对象?
更多细节:
1)我的源代码是一个PDF页面,包含图像和文本(可能是一些矢量图)和嵌入的字体。
2)有一个设计多个"裁剪框"的界面。
3)我必须生成一个新的PDF,它只包含裁剪框内的内容。其他任何东西都必须从结果文档中删除(实际上我可以接受一半在里面一半在外面的内容,但这不是理想的,无论如何都不应该出现)。
我的解决方案:
我已经成功地开发了一个解决方案,创建新的临时文档,每个文档包含每个裁剪框的内容(使用writer)。getimporttedpage和contentByte。AddTemplate添加到与裁剪框大小相同的页面)。然后我创建最终文档并重复这个过程,使用AddTemplate方法在最终页面中定位每个"裁剪页面"。
这个解决方案有两个很大的缺点:
- 文档的大小是[原始大小]*[裁剪框数],因为整个页面都在那里,盖章多次!(看不见,但它在那里)
- 不可见的文本仍然可以通过在Reader中选择all (CTRL+A)并粘贴来访问。
所以,我认为我需要遍历PDF对象,检测它是否可见,并删除它。在撰写本文时,我正在尝试使用pdfReader.GetPdfObject.
谢谢你的帮助
如果您正在尝试的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");
PdfReader pdfReader = new PdfReader(../Template_Path.pdf"));
PdfStamper pdfStamperToPopulate = new PdfStamper(pdfReader, new FileStream(outputPath, FileMode.Create));
AcroFields pdfFormFields = pdfStamperToPopulate.AcroFields;
pdfFormFields.RemoveField("fieldNameToBeRemoved");
是的,有可能。您需要将pdf页面内容字节解析为PdfObject,将它们存储到内存中,删除不需要的PdfObject,从PdfObject的返回到pdf内容字节中构建pdf内容,在PdfWriter导入页面之前替换PdfReader中的页面内容。
我建议你看看这个:http://habjan.blogspot.com/2013/09/proof-of-concept-converting-pdf-files.html
链接中的示例实现了Pdf内容字节解析,从PdfObjec的重新构建,替换PdfReader页面内容字节…
以下是我发现的三个解决方案,如果它能帮助别人(使用iTextSharp, Amyuni或Tracker-Software,正如@Hetote在评论中说的,他正在寻找另一个库):
使用iTextSharp正如@martinbuberl在另一个问题中的回答:
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();
}
@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 正如@yms在另一个问题中的回答:
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在评论中所说,使用新方法IacDocument的另一个解决方案。版本5.0中的编辑还可用于删除指定矩形中的所有对象,并在其位置绘制纯色矩形。
使用跟踪软件编辑器SDK
我没有尝试过,但似乎是可能的,看看这篇文章
你试过使用IRenderListener吗?您可以通过检查TextRenderInfo或ImageRenderInfo对象的StartPoint和EndPoint或Area,有选择地将这些元素添加到新pdf中,这些元素落在裁剪区域内。