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

如何解决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文件:之前
- 之后

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?