2017-06-01 73 views
0

我需要从iText 5.5.11中的Jasper Reports创建的现有pdf中删除一些内容,但是在运行PdfCleanUpProcessor之后,所有粗体文本都模糊不清。iText 5.5.11 - 在使用PdfCleanUpProcessor后,粗体文本看起来模糊

这是我使用的代码:

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(); 

前面已经讨论过here降级到iText的-5.5.4解决了这个问题,但对我来说iText的-5.5.11已经在使用其他原因和降级不是一种选择。

是否有其他解决方案或解决方法?

这是PDF文件前和清洗后:BEFORE - AFTER

+0

请分享我们可以重现问题的PDF。 – mkl

+0

@mkl使用“BEFORE”PDF重现问题 – Tieco

+0

嗯,好的,对不起,我没有正确阅读您的问题文本,并预期只有图像。我会看看。 – mkl

回答

0

通过比较之前文件很清楚,由于某些原因,PdfCleanUpProcessor错误降到一般的图形状态的操作(至少w,Jd)。


在你之前文件,特别是因为一个穷人的大胆变体使用,即而不是使用实际的粗体使用正常字体和W¯¯操作的文本很重要文本渲染模式不仅可以填充字形轮廓,还可以沿着它画一条线,使其具有大胆的外观。

使用w操作将该行的宽度设置为0.23333。由于文档中的中缺少该操作,因此使用默认宽度值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将同时下降同时试图将更改后的值存储在清理策略上下文中。但是当然使用==代替String在Java中的比较通常是一个非常糟糕的主意,所以自该版本以来,线型运算符在iText中的性能下降了。

其实这段代码已经从iTextSharp移植过来了,在C#==中为string类型的作品完全不同;尽管如此,即使在iTextSharp版本中,这些存储的值乍一看似乎只在路径被抚摸时才被考虑到,而不是如果文本渲染包括沿轮廓抚摸。

后来在提交9967627(在同一天与上述提交)内if..else if..else..已经与来自itext.pdf.parser包现有GraphicsState代替PdfCleanUpGraphicsState注释删除,添加缺少的参数到后者,只有disableOutput = true保持。这(乍一看)似乎已经解决了iText/Java和iTextSharp/.Net之间的差异,但是如果文本呈现包括沿着轮廓线描边,线样式值仍然不被考虑。


作为一种变通考虑删除线

} else if (lineStyleOperators.contains(operatorStr)) { 
    disableOutput = true; 

PdfCleanUpContentOperator.invoke。现在线样式运算符不再被删除,编辑后的PDF中的文本看起来像之前一样。尽管如此,我还没有检查过任何副作用,所以在考虑在生产中使用该解决方案之前,请先用一些文档进行测试。

+0

谢谢并为延迟感到抱歉。我会尝试建议的解决方法并让您知道 – Tieco

+0

您的解释有助于我理解此问题的原因。不幸的是,提出的解决方法意味着修改了itext库,我无法确保定制版本将来不会被更新。可能最好的选择是改变粗体的生成方式。 – Tieco

+0

或者,您可以将清理软件包中的所有内容复制到您自己的软件包中,然后在其中应用修复程序。不是最优雅的解决方案,但那是什么! – mkl

相关问题