基于iText 8实现任意角度旋转PdfPolyGeomAnnotation的技术求助
如何用iText 8正确旋转PdfPolyGeomAnnotation(多边形注释)
我需要将PdfAnnotation旋转至任意角度,目前尝试用iText 8实现PdfPolyGeomAnnotation(多边形)的旋转。根据现有示例和手动绘制的旋转多边形,确认该需求可实现。
测试情况
在Sample-orig.pdf中有4个测试多边形:
- 第一个是未旋转的对照多边形,由
PlacePolygon1方法生成; - 第二个采用
PlacePolygon2方法,试图匹配Sample-test.pdf中手动绘制的旋转多边形结构; - 第三、第四个分别用
PlacePolygon3和PlacePolygon4方法,尝试不同的旋转实现逻辑。
问题现象
第二个多边形实际已被旋转(可被选中),但显示异常。若对其进行轻微修改(如上下移动后复位),异常会消失并正常显示(详见Sample-adjusted1.pdf)。
Appearance Dictionary(AP)差异分析
对比发现异常多边形与正常多边形的AP条目长度存在明显差异:
- Sample-orig.pdf中异常多边形的AP长度为8;
- Sample-adjusted1.pdf中修复后的AP长度为78;
- Sample-test.pdf中手动绘制的正常多边形AP长度为113。
这说明异常多边形的AP字典缺少必要内容,但无法确定具体缺失项及补充方式。
关联文件说明
- Sample-orig.pdf:程序生成的原始输出文件
- Sample-adjusted1.pdf:与Sample-orig.pdf一致,仅对问题多边形进行了轻微移动后复位操作
- Sample-test.pdf:包含手动绘制并旋转的多边形,展示预期效果
代码实现
public static void PlacePolygon2(PdfPage pdfPage) { float rotation = 15.0f; float x = 700f; float y = 1000f; float w = 300f; float h = 100f; float[] verts = new [] { x , y, x + w - 50f, y, x + w , y + h, x + 50f , y + h, x , y }; Rectangle r = new Rectangle(verts[0], verts[1], w, h); PdfPolyGeomAnnotation poly = PdfPolyGeomAnnotation.CreatePolygon(r, verts); PdfFormXObject xo = null; poly.SetColor(DeviceRgb.RED); poly.SetInteriorColor(DeviceRgb.GREEN.GetColorValue()); poly.SetOpacity(new PdfNumber(0.4)); poly.SetStrokingOpacity(0.7f); // 此部分试图模拟手动放置的旋转多边形的信息 // 开始 float rot = FloatOps.ToRad(rotation); AffineTransform af = AffineTransform.GetRotateInstance(rot, verts[0], verts[1]); float[] mx = new float[6]; af.GetMatrix(mx); // mx[4] = -671f; // mx[5] = -1286f; PdfArray pdfArray = new PdfArray(mx); PdfArray pdfArray2 = new PdfArray(new float[] {r.GetX()-100f, r.GetY()-100f, 500f, 500f }); Rectangle bb = new Rectangle( r.GetX() - 100f, r.GetY() - 100f, 500f, 500f); Collection<KeyValuePair<PdfName, PdfObject>> col = new Collection<KeyValuePair<PdfName, PdfObject>>(); col.Add(new KeyValuePair<PdfName, PdfObject>(PdfName.BBox, pdfArray2)); col.Add(new KeyValuePair<PdfName, PdfObject>(PdfName.Matrix, pdfArray)); poly.Put(new PdfName("Rotation"), new PdfNumber(rotation)); xo = new PdfFormXObject(bb); xo.Put(PdfName.Matrix, new PdfArray(pdfArray)); PdfExtGState gs3 = new PdfExtGState(); gs3.SetFillOpacity(.6f); gs3.SetStrokeOpacity(0.7f); gs3.Put(PdfName.Type, PdfName.ExtGState); PdfExtGState gs2 = new PdfExtGState(gs3.GetPdfObject()); PdfDictionary pd1 = new PdfDictionary(); pd1.Put(new PdfName("BBGS"), gs2.GetPdfObject()); PdfExtGState gs = new PdfExtGState(); gs.SetLineWidth(2f); gs.Put(PdfName.ExtGState, pd1); gs.Put(PdfName.Type, PdfName.ExtGState); gs.Put(PdfName.BorderColor, new PdfArray(new float[] { 1, 0, 0 })); gs.Put(PdfName.Color, new PdfArray(new float[] { 0, 0, 1 })); PdfResources res = new PdfResources(gs.GetPdfObject()); res.SetProcSet(new PdfArray(new List<PdfObject>(){new PdfName("PDF")} )); xo.Put(PdfName.Resources, res.GetPdfObject()); poly.SetNormalAppearance(xo.GetPdfObject()); // 结束 poly.SetFlag(0); poly.SetName(new PdfString("poly1")); poly.Put(PdfName.Type, PdfName.Annot); pdfPage.AddAnnotation(poly); } // 普通未旋转多边形 public static void PlacePolygon1(PdfPage pdfPage) { float rotation = 15.0f; float x = 200f; float y = 1000f; float w = 300f; float h = 100f; float[] verts = new [] { x , y, x + w - 50f, y, x + w , y + h, x + 50f , y + h, x , y }; Rectangle r = new Rectangle(verts[0], verts[1], w, h); PdfPolyGeomAnnotation poly = PdfPolyGeomAnnotation.CreatePolygon(r, verts); poly.SetColor(DeviceRgb.RED); poly.SetInteriorColor(DeviceRgb.GREEN.GetColorValue()); poly.SetOpacity(new PdfNumber(0.4)); poly.SetStrokingOpacity(0.7f); pdfPage.AddAnnotation(poly); } // 多边形旋转实现版本2 public static void PlacePolygon3(PdfPage pdfPage) { float rotation = 15.0f; float x = 1200f; float y = 1000f; float w = 300f; float h = 100f; float[] verts = new [] { x , y, x + w - 50f, y, x + w , y + h, x + 50f , y + h, x , y }; Rectangle r = new Rectangle(verts[0], verts[1], w, h); PdfPolyGeomAnnotation poly = PdfPolyGeomAnnotation.CreatePolygon(r, verts); poly.SetColor(DeviceRgb.RED); poly.SetInteriorColor(DeviceRgb.GREEN.GetColorValue()); poly.SetOpacity(new PdfNumber(0.4)); poly.SetStrokingOpacity(0.7f); poly.Put(PdfName.Rotate, new PdfNumber(15.0)); pdfPage.AddAnnotation(poly); } // 多边形旋转实现版本3 public static void PlacePolygon4(PdfPage pdfPage) { float rotation = 15.0f; float x = 1700f; float y = 1000f; float w = 300f; float h = 100f; float[] verts = new [] { x , y, x + w - 50f, y, x + w , y + h, x + 50f , y + h, x , y }; Rectangle r = new Rectangle(verts[0], verts[1], w, h); PdfPolyGeomAnnotation poly = PdfPolyGeomAnnotation.CreatePolygon(r, verts); poly.SetColor(DeviceRgb.RED); poly.SetInteriorColor(DeviceRgb.GREEN.GetColorValue()); poly.SetOpacity(new PdfNumber(0.4)); poly.SetStrokingOpacity(0.7f); poly.Put(new PdfName("Rotation"), new PdfNumber(15.0)); pdfPage.AddAnnotation(poly); }
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

