Java iText 5.5.11-使用PdfCleanUpProcessor后,粗体文本看起来模糊
我需要从iText 5.5.11中使用Jasper Reports创建的现有pdf中删除一些内容,但在运行PdfCleanUpProcessor后,所有粗体文本都变得模糊 这是我正在使用的代码:Java iText 5.5.11-使用PdfCleanUpProcessor后,粗体文本看起来模糊,java,pdf,itext,Java,Pdf,Itext,我需要从iText 5.5.11中使用Jasper Reports创建的现有pdf中删除一些内容,但在运行PdfCleanUpProcessor后,所有粗体文本都变得模糊 这是我正在使用的代码: PdfReader reader = new PdfReader("input.pdf"); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("output.pdf")); List<PdfCleanUpLocati
PdfReader reader = new PdfReader("input.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("output.pdf"));
List<PdfCleanUpLocation> cleanUpLocations = new ArrayList<PdfCleanUpLocation>();
cleanUpLocations.add(new PdfCleanUpLocation(1, new Rectangle(0f, 0f, 595f, 680f)));
PdfCleanUpProcessor cleaner = new PdfCleanUpProcessor(cleanUpLocations, stamper);
cleaner.cleanUp();
stamper.close();
reader.close();
PdfReader=newpdfReader(“input.pdf”);
PdfStamper stamper=新PdfStamper(读取器,新文件输出流(“output.pdf”);
List cleanUpLocations=new ArrayList();
添加(新的PdfCleanUpLocation(1,新的矩形(0f,0f,595f,680f));
PdfCleanUpProcessor cleaner=新的PdfCleanUpProcessor(cleanUpLocations,stamper);
cleaner.cleanUp();
压模关闭();
reader.close();
如前所述,降级到itext-5.5.4解决了问题,但在我的例子中,itext-5.5.11由于其他原因已经在使用,因此降级不是一个选项
是否有其他解决方案或解决方法
这是清理前后的pdf文件:-通过比较清理前后的文件,可以清楚地看出,由于某种原因,PdfCleanUpProcessor
错误地删除了常规图形状态操作(至少w、J和d)
尤其是在您的before文档中,w操作对于文本非常重要,因为使用了穷人的粗体变体,即使用普通字体而不是实际的粗体字体,并且文本渲染模式设置为不仅填充字形轮廓,还沿轮廓绘制一条线,使其具有粗体外观 使用w操作将该行的宽度设置为0.23333。由于after文档中缺少该操作,因此使用默认宽度值1。因此,现在沿着轮廓线的线条是以前的4倍大,从而形成了非常肥胖的外观
此问题已在提交d5abd23(日期为2015年5月4日)中引入,其中(除其他事项外)将此块添加到了
PdfCleanUpContentOperator.invoke
:
} else if (lineStyleOperators.contains(operatorStr)) {
if ("w" == operatorStr) {
cleanUpStrategy.getContext().setLineWidth(((PdfNumber) operands.get(0)).floatValue());
} else if ("J" == operatorStr) {
cleanUpStrategy.getContext().setLineCapStyle(((PdfNumber) operands.get(0)).intValue());
} else if ("j" == operatorStr) {
cleanUpStrategy.getContext().setLineJoinStyle(((PdfNumber) operands.get(0)).intValue());
} else if ("M" == operatorStr) {
cleanUpStrategy.getContext().setMiterLimit(((PdfNumber) operands.get(0)).floatValue());
} else if ("d" == operatorStr) {
cleanUpStrategy.getContext().setLineDashPattern(new LineDashPattern(((PdfArray) operands.get(0)),
((PdfNumber) operands.get(1)).floatValue()));
}
disableOutput = true;
这会导致删除所有lineStyleOperators
,同时尝试将更改的值存储在清理策略上下文中。当然,在Java中使用==
进行String
比较通常是一个非常糟糕的主意,因此由于这个版本,在iText中删除了行样式运算符
实际上,这段代码是从iTextSharp移植的,在C#==
中,对于字符串
类型,工作方式完全不同;尽管如此,即使在iTextSharp版本中,这些存储值乍一看似乎只有在路径被笔划时才被考虑,而不是在文本渲染包括沿轮廓笔划时才被考虑
稍后在提交9967627中(与上述提交的同一天),内部的if..else if..else..
已被删除,注释替换为PdfCleanUpGraphicsState
,替换为itext.pdf.parser中现有的GraphicsState
,在后者中添加了缺失的参数,只剩下disableOutput=true
。这(乍一看)似乎修复了iText/Java和iTextSharp/.Net之间的差异,但如果文本渲染包括沿轮廓笔划,则仍然不考虑线条样式值
作为一个工作考虑删除线< /P>
} else if (lineStyleOperators.contains(operatorStr)) {
disableOutput = true;
从PdfCleanUpContentOperator.invoke
。现在不再删除线条样式操作符,并且PDF中的文本在编辑后看起来与以前一样。不过,我还没有检查任何副作用,所以在考虑在生产中使用该解决方案之前,请使用大量文档进行测试。请与我们共享一个PDF,我们可以复制该问题。@mkl使用“before”PDF复制该问题。啊,好的,对不起,我没有正确阅读您的问题文本,只需要图像。我去看看。谢谢,抱歉耽搁了。我将尝试建议的解决方法,并让您知道您的解释有助于我理解此问题的原因。不幸的是,建议的解决方案意味着修改itext库,我不能确保将来不会更新自定义版本。也许最好的选择是更改粗体的生成方式。或者,您可以将清理包中的所有内容复制到您自己的包中,并在其中应用修复程序。这不是最优雅的解决方案,但又怎么样!在我的例子中,将页面的一部分复制为图像并粘贴到新的pdf页面上也可以。用iText可以吗?(我知道iText不用于渲染,但我不需要将图像保存到文件系统)要将页面的一部分复制为图像,您需要实际渲染它,而iText(尚未)实现将PDF渲染为图像。