iText 5.5.11 - 使用PdfCleanUpProcessor后,粗体文本看起来很模糊 [英] iText 5.5.11 - bold text looks blurry after using PdfCleanUpProcessor

查看:891
本文介绍了iText 5.5.11 - 使用PdfCleanUpProcessor后,粗体文本看起来很模糊的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to remove some content from an existing pdf created with Jasper Reports in iText 5.5.11 but after running PdfCleanUpProcessor all bold text is blurry.

这是我正在使用的代码:

This is the code I'm using:

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已经被用于其他原因因此降级不是一种选择。

As already discussed here downgrading to itext-5.5.4 solves the problem, but in my case itext-5.5.11 is already in use for other reasons and so downgrading is not an option.

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

Is there another solution or workaround?

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

This are the pdf files before and after cleaning: BEFORE - AFTER

推荐答案

通过比较之前的之后的,很明显由于某种原因, PdfCleanUpProcessor 错误地删除了一般的图形状态操作(至少 w J d )。

By comparing the before and after files it becomes clear that for some reason the PdfCleanUpProcessor falsely drops general graphics state operations (at least w, J, and d).

之前文档中,特别是 w 操作对于文本因为使用穷人的粗体变体,即使用普通字体而不是使用实际的粗体字体,并且文本渲染模式设置为不仅填充字形轮廓而且还绘制线条沿着它给它一个大胆的外观。

In your before document in particular the w operation is important for the text because a poor man's bold variant is used, i.e. instead of using an actual bold font the normal font is used and the text rendering mode is set to not only fill the glyph contours but also draw a line along it giving it a bold'ish appearance.

使用 w 操作将该行的宽度设置为0.23333。由于文档之后缺少该操作,因此使用默认宽度值1。因此,沿着轮廓的线条现在是之前的4倍,导致非常胖的外观。

The width of that line is set to 0.23333 using a w operation. As that operation is missing in the after document, the default width value of 1 is used. Thus, the line along the contour now is 4 times as big as before resulting in a very fat appearance.

此问题已在commit d5abd23(2015年5月4日)中引入,其中(除其他外)将此块添加到 PdfCleanUpContentOperator.invoke

This issue has been introduced in commit d5abd23 (dated May 4th, 2015) which (among other things) added this block to 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中被删除了。

This causes all lineStyleOperators to be dropped while at the same time an attempt was made to store the changed values in the cleanup strategy context. But of course using == for String comparisons in Java usually is a very bad idea, so since this version the line style operators were dropped for good in iText.

实际上这段代码已从iTextSharp移植,并在C# == 对于字符串类型完全不同;尽管如此,即使在iTextSharp版本中,如果路径被描边,乍一看这些存储的值似乎也只被考虑在内,而不是文本渲染包括沿着轮廓描边。

Actually this code had been ported from iTextSharp, and in C# == for the string type works entirely different; nonetheless, even in the iTextSharp version these stored values at first glance only seem to have been taken into account if paths were stroked, not if text rendering included stroking along the contour.

稍后在提交9967627(与上面提交的同一天)内部 if..else if..else .. 已被删除,注释 itext.pdf.parser 中的现有 GraphicsState 替换 PdfCleanUpGraphicsState 包,将缺少的参数添加到后者中,只剩下 disableOutput = true 。这(也乍一看)似乎已经修复了iText / Java和iTextSharp / .Net之间的差异,但如果文本渲染包括沿轮廓描边,则仍然不考虑线型值。

Later on in commit 9967627 (on the same day as the commit above) the inner if..else if..else.. has been removed with the comment Replaced PdfCleanUpGraphicsState with existing GraphicsState from itext.pdf.parser package, added missing parameters into the latter, only the disableOutput = true remained. This (also at first glance) appears to have fixed the difference between iText/Java and iTextSharp/.Net, but the line style values still are not considered if text rendering included stroking along the contour.

作为一种解决方法,考虑删除行

As a work-around consider removing the lines

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

来自 PdfCleanUpContentOperator.invoke 。现在,线条样式运算符不再被删除,并且编辑后的PDF中的文本看起来像以前一样。但是,我没有检查任何副作用,所以请在测试之前使用一些文件进行测试。

from PdfCleanUpContentOperator.invoke. Now the line style operators are not dropped anymore and the text in your PDF after redaction looks like before. I have not checked for any side effects, though, so please test with a number of documents before even considering using that work-around in production.

这篇关于iText 5.5.11 - 使用PdfCleanUpProcessor后,粗体文本看起来很模糊的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆