使用PDFBox缩放PDF页面时嵌入字体丢失的原因?
PDFBox 3.x缩放PDF页面导致嵌入字体丢失的原因及解决方法
问题原因
你通过PDPageContentStream.AppendMode.PREPEND模式添加全局缩放变换的操作,触发了PDFBox 3.x(包括3.0.0和3.0.2版本)的资源处理问题:在重新序列化页面内容流的过程中,PDFBox没有正确保留原始页面资源字典中的嵌入字体引用。当你关闭内容流并修改MediaBox后,输出PDF的页面资源字典丢失了字体条目,导致阅读器无法识别嵌入字体。
解决方法
方法1:使用UserUnit属性实现缩放(推荐)
无需修改内容流,直接通过调整页面的UserUnit属性结合MediaBox设置完成缩放,这种方式能完全保留原始资源:
public void scale(PDDocument pdf, PDPage page) throws IOException { // 设置UserUnit实现缩放,factor为你的缩放比例(默认UserUnit值为1) page.setUserUnit(factor); // 调整目标MediaBox page.setMediaBox(targetMediaBox); }
方法2:手动保留原始资源(适配必须使用内容流变换的场景)
如果必须通过内容流添加变换,需要在创建PDPageContentStream时手动合并原始页面的资源,确保字体引用不丢失:
public void scale(PDDocument pdf, PDPage page) throws IOException { PDResources originalResources = page.getResources(); // 创建内容流时开启resetContext,确保资源上下文正确初始化 PDPageContentStream contentStream = new PDPageContentStream(pdf, page, PDPageContentStream.AppendMode.PREPEND, false, true); // 将原始页面的资源合并到内容流的资源字典中 contentStream.getResources().addAll(originalResources); contentStream.transform(Matrix.getScaleInstance(factor, factor)); contentStream.close(); page.setMediaBox(targetMediaBox); }
内容的提问来源于stack exchange,提问作者FabianTe
相关产品推荐
相关产品推荐

