ofdrw项目中Annot类型图片渲染异常问题分析与解决
问题背景
在ofdrw项目2.3.5版本中,开发人员发现了一个关于Annot类型图片渲染的问题。具体表现为当处理OFD文档中的注释(Annotation)时,特别是包含图片的Watermark类型注释,图片的大小和位置会出现异常,与预期效果不符。
问题分析
通过对代码的深入检查,发现问题出在org/ofdrw/converter/ItextMaker.java文件中。当处理Annot类型的图片时,系统没有正确进行DPI(每英寸点数)转换,导致图片在PDF输出中的尺寸和位置计算出现偏差。
在OFD文档中,注释(Annotation)通常用于添加水印、批注等额外信息。这些注释可以包含图片或文本对象,并通过边界框(Boundary)和变换矩阵(CTM)来定义它们在页面上的位置和大小。
技术细节
问题的核心在于坐标系统的转换。OFD文档使用毫米(mm)作为基本单位,而PDF内部使用点(pt)作为基本单位。在标准情况下,1英寸=25.4毫米=72点,因此需要进行适当的单位转换。
在原始代码中,当处理Annot类型的图片时,直接使用了OFD文档中的坐标值而没有进行DPI转换。这导致图片在PDF中的实际大小和位置与预期不符,因为两者使用了不同的度量单位。
解决方案
解决方案是在调用addImageWithTransformationMatrix方法进行图片渲染时,对坐标和尺寸值进行DPI转换。具体修改包括:
- 获取注释的边界框(annotBox)信息
- 提取注释的x、y坐标以及宽度、高度
- 对这些值应用
converterDpi方法进行单位转换 - 将转换后的值传递给图片渲染方法
对于文本注释的处理,由于使用了不同的变换矩阵,保持了原有的处理逻辑不变。
代码示例
以下是修改后的关键代码片段:
if (annotBox != null && !isSameBox(annotBox, imageObject.getBoundary())) {
float x = annotBox.getTopLeftX().floatValue();
float y = box.getHeight().floatValue() - (annotBox.getTopLeftY().floatValue() + annotBox.getHeight().floatValue());
float width = annotBox.getWidth().floatValue();
float height = annotBox.getHeight().floatValue();
pdfCanvas.addImageWithTransformationMatrix(image,
(float)converterDpi(width), 0, 0, (float)converterDpi(height),
(float)converterDpi(x), (float)converterDpi(y));
} else {
// 保持原有矩阵变换逻辑
org.apache.pdfbox.util.Matrix matrix = CommonUtil.toPFMatrix(CommonUtil.getImageMatrixFromOfd(imageObject, box, compositeObjectCTM));
float a = matrix.getValue(0, 0);
float b = matrix.getValue(0, 1);
float c = matrix.getValue(1, 0);
float d = matrix.getValue(1, 1);
float e = matrix.getValue(2, 0);
float f = matrix.getValue(2, 1);
pdfCanvas.addImageWithTransformationMatrix(image, a, b, c, d, e, f);
}
总结
这个问题的解决展示了在处理文档格式转换时,单位系统转换的重要性。OFD和PDF使用不同的基本单位,因此在转换过程中必须进行适当的计算。特别是在处理注释这类特殊元素时,更需要仔细检查坐标和尺寸的转换逻辑。
通过这次修复,ofdrw项目能够更准确地处理包含图片注释的OFD文档,确保在转换为PDF时保持原始文档的布局和视觉效果。这对于需要精确文档转换的应用场景尤为重要,如电子公文、电子合同等专业领域。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



