iText 5.5.11-使用PdfCleanUpProcessor后粗体文本看起来模糊

问题描述

通过比较文件 之前之后 ,可以清楚地看出,由于某种原因,PdfCleanUpProcessor错误地放弃了常规图形状态操作(至少 , 和 )。


特别是在您的 之前 文档中, 操作对于文本非常重要,因为使用了 穷人的粗体 变体,即,使用常规字体代替了实际的粗体字体,并且将文本呈现模式设置为不仅填充字形轮廓并沿其画一条线,使其外观大胆。

使用 操作将该行的宽度设置为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..已被删除,并带有注释 替换 为包中的PdfCleanUpGraphicsState现有内容,并向后者添加了缺少的参数GraphicsState``itext.pdf.parser,仅disableOutput = true保留了剩余的参数。这(乍看起来)似乎已经解决了iText / Java和iTextSharp / .Net之间的差异,但是,如果文本渲染包括沿轮廓笔划,则仍不考虑线型值。


作为解决方法,请考虑删除

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

来自PdfCleanUpContentOperator.invoke。现在,不再删除线型运算符,并且编辑后的PDF中的文本看起来像以前一样。不过,我尚未检查任何副作用,因此,即使考虑在生产中使用该替代方法,也请先测试大量文档。

解决方法

我需要从使用iText 5.5.11中的Jasper
Reports创建的现有pdf中删除一些内容,但是运行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();

正如这里已经讨论的那样,降级到itext-5.5.4可以解决问题,但是在我的情况下,由于其他原因,已经使用了itext-5.5.11,因此降级不是一种选择。

还有其他解决方案或解决方法吗?

这是清洁前后的pdf文件:之前
- 之后

喜欢与人分享编程技术与工作经验,欢迎加入编程之家官方交流群!

猜你在找的编程问答相关文章

在Pandas数据框中旋转数据表
如何获得浮点序列中的下一个值?
获取Instagram粉丝
在批处理结束时检测到不可提交的事务。交易回滚
将一个文本文件文件夹与一个单元格中的每个内容合并为一个CSV文件
在使用JSON数据时,如何防止我的应用程序意外崩溃,“关闭”,而代之以处理异常?
JDBC批处理INSERT,返回ID
具有多个表的复杂INNER JOIN查询的回显结果
微信公众号搜索 “ 程序精选 ” ,选择关注!
微信公众号搜 "程序精选"关注