在 iText 7 中标记文本后缺少字体资源字典
Missing font resource dictionary after stamping text in iText 7
我现有的 PDF 不包含任何字体(仅图像)。我想使用低级 canvas 操作在第一页上标记一些额外的文本。当我在 iText 7 中执行此操作时,生成的 PDF 缺少字体资源字典条目(在解析生成的文件时会导致 NPE)。
我是否必须执行 canvas.setFontAndSize() 之外的操作才能将字体资源添加到输出中?
这是重现问题的单元测试:
public class CheckFontResourceInclusion {
@Test
public void test() throws Exception {
// create a document to stamp
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try(PdfDocument doc = new PdfDocument(new PdfWriter(baos))){
doc.addNewPage();
}
// stamp it
StampingProperties stampProps = new StampingProperties();
PdfFont font = PdfFontFactory.createFont();
ByteArrayOutputStream resultStream = new ByteArrayOutputStream();
try(PdfDocument doc = new PdfDocument(new PdfReader(new ByteArrayInputStream(baos.toByteArray())), new PdfWriter(resultStream), stampProps)){
PdfPage page = doc.getPage(1);
PdfCanvas canvas = new PdfCanvas(page.newContentStreamAfter(), new PdfResources(), doc);
canvas.beginText();
canvas.setTextRenderingMode(2);
canvas.setFontAndSize(font, 42);
canvas.setTextMatrix(1, 0, 0, -1, 100, 100);
canvas.showText("TEXT TO STAMP");
canvas.endText();
}
// parse text
try(PdfDocument doc = new PdfDocument(new PdfReader(new ByteArrayInputStream(resultStream.toByteArray())))){
LocationTextExtractionStrategy strat = new LocationTextExtractionStrategy();
PdfCanvasProcessor processor = new PdfCanvasProcessor(strat);
processor.processPageContent(doc.getPage(1));
Assert.assertEquals("TEXT TO STAMP", strat.getResultantText());
}
}
}
这是失败的结果:
java.lang.NullPointerException
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor$SetTextFontOperator.invoke(PdfCanvasProcessor.java:811)
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor.invokeOperator(PdfCanvasProcessor.java:456)
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor.processContent(PdfCanvasProcessor.java:285)
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor.processPageContent(PdfCanvasProcessor.java:306)
at
错误与此相同:您使用了一次性资源对象,因此结果中缺少字体资源。
您可以使用实际的页面资源来解决这个问题。只需替换
PdfCanvas canvas = new PdfCanvas(page.newContentStreamAfter(), new PdfResources(), doc);
来自
PdfCanvas canvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), doc);
我现有的 PDF 不包含任何字体(仅图像)。我想使用低级 canvas 操作在第一页上标记一些额外的文本。当我在 iText 7 中执行此操作时,生成的 PDF 缺少字体资源字典条目(在解析生成的文件时会导致 NPE)。
我是否必须执行 canvas.setFontAndSize() 之外的操作才能将字体资源添加到输出中?
这是重现问题的单元测试:
public class CheckFontResourceInclusion {
@Test
public void test() throws Exception {
// create a document to stamp
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try(PdfDocument doc = new PdfDocument(new PdfWriter(baos))){
doc.addNewPage();
}
// stamp it
StampingProperties stampProps = new StampingProperties();
PdfFont font = PdfFontFactory.createFont();
ByteArrayOutputStream resultStream = new ByteArrayOutputStream();
try(PdfDocument doc = new PdfDocument(new PdfReader(new ByteArrayInputStream(baos.toByteArray())), new PdfWriter(resultStream), stampProps)){
PdfPage page = doc.getPage(1);
PdfCanvas canvas = new PdfCanvas(page.newContentStreamAfter(), new PdfResources(), doc);
canvas.beginText();
canvas.setTextRenderingMode(2);
canvas.setFontAndSize(font, 42);
canvas.setTextMatrix(1, 0, 0, -1, 100, 100);
canvas.showText("TEXT TO STAMP");
canvas.endText();
}
// parse text
try(PdfDocument doc = new PdfDocument(new PdfReader(new ByteArrayInputStream(resultStream.toByteArray())))){
LocationTextExtractionStrategy strat = new LocationTextExtractionStrategy();
PdfCanvasProcessor processor = new PdfCanvasProcessor(strat);
processor.processPageContent(doc.getPage(1));
Assert.assertEquals("TEXT TO STAMP", strat.getResultantText());
}
}
}
这是失败的结果:
java.lang.NullPointerException
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor$SetTextFontOperator.invoke(PdfCanvasProcessor.java:811)
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor.invokeOperator(PdfCanvasProcessor.java:456)
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor.processContent(PdfCanvasProcessor.java:285)
at com.itextpdf.kernel.pdf.canvas.parser.PdfCanvasProcessor.processPageContent(PdfCanvasProcessor.java:306)
at
错误与此相同
您可以使用实际的页面资源来解决这个问题。只需替换
PdfCanvas canvas = new PdfCanvas(page.newContentStreamAfter(), new PdfResources(), doc);
来自
PdfCanvas canvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), doc);