PDFBox插入PDPushButton的图片在pdf.js(火狐浏览器)中不可见
问题根源
你代码里的外观流(Appearance Stream)使用了页面全局坐标设置BBox和绘制图片,但PDF规范中,Widget注释的外观流坐标空间是相对于注释自身的矩形区域(以注释左下角为原点(0,0))。pdf.js对该规范的校验比其他渲染器更严格,因此导致图片无法渲染。
修复后的代码
调整外观流的BBox和图片绘制坐标,改用相对坐标:
PDPushButton pdPushButton = (PDPushButton) field; List<PDAnnotationWidget> widgets = pdPushButton.getWidgets(); if (widgets != null && widgets.size() > 0) { PDAnnotationWidget annotationWidget = widgets.get(0); String filePath = item.getValue(); File imageFile = new File(filePath); if (imageFile.exists()) { PDImageXObject pdImageXObject = PDImageXObject.createFromFile(filePath, document); float imageScaleRatio = (float) pdImageXObject.getHeight() / (float) pdImageXObject.getWidth(); PDRectangle buttonPosition = getFieldArea(pdPushButton); float height = buttonPosition.getHeight(); float width = height / imageScaleRatio; PDAppearanceStream pdAppearanceStream = new PDAppearanceStream(document); pdAppearanceStream.setResources(new PDResources()); try (PDPageContentStream pdPageContentStream = new PDPageContentStream(document, pdAppearanceStream)) { // 以外观流本地坐标(0,0)为起点绘制图片 pdPageContentStream.drawImage(pdImageXObject, 0, 0, width, height); } // 设置BBox为外观流本地的宽高,原点(0,0) pdAppearanceStream.setBBox(new PDRectangle(0, 0, width, height)); PDAppearanceDictionary pdAppearanceDictionary = annotationWidget.getAppearance(); if (pdAppearanceDictionary == null) { pdAppearanceDictionary = new PDAppearanceDictionary(); annotationWidget.setAppearance(pdAppearanceDictionary); } pdAppearanceDictionary.setNormalAppearance(pdAppearanceStream); System.out.println("Image '" + filePath + "' inserted"); field.setReadOnly(true); } }
额外说明
如果需要让图片在按钮区域内居中或调整位置,仍需基于(0,0)的相对坐标计算偏移量,而非使用页面全局坐标。修改后,pdf.js和其他PDF渲染器均可正确识别并显示图片。
内容的提问来源于stack exchange,提问作者Vas K
相关产品推荐
相关产品推荐

