iText中SetRotationAngle不生效:单图片多引用旋转问题
解决iText中复用图片并设置不同旋转角度的问题
问题原因
你之前的代码无法实现旋转的核心原因有两个:
SetRotationAngle是修改Image实例的属性,生成XObject后,旋转参数会固化到XObject中,复用该XObject时所有引用都会使用同一旋转角度,无法实现差异化旋转。AddXObjectFittedIntoRectangle方法会直接按目标矩形尺寸放置XObject,不会读取Image实例的旋转设置,因此即使你设置了旋转也不会生效。
正确解决方案
要实现单图片仅加载一次、多次复用且每张带不同旋转角度的效果,应该通过画布的矩阵变换来实现旋转,而不是修改XObject本身。具体步骤如下:
1. 初始化可复用的XObject(仅执行一次)
先加载图片并生成XObject,保留原有的高效复用逻辑:
// 仅执行一次:加载图片字节数组生成ImageData ImageData imageData = ImageDataFactory.Create(MyImage); // 将Image转为可复用的PdfXObject PdfXObject imageXObject = new Image(imageData).GetXObject();
2. 多次绘制带不同旋转的图片
每次绘制时,通过操作画布的变换矩阵实现旋转,绘制完成后恢复画布状态,避免影响后续内容:
// 假设每次绘制的位置(Pos)、尺寸(Size)、旋转弧度(radians)均不同 Rectangle targetRect = new Rectangle(Pos.X, Pos.Y, Size.X, Size.Y); // 保存当前画布状态,防止变换影响后续绘制 gfx.SaveState(); // 计算旋转中心:这里以目标矩形的中心为例 float centerX = targetRect.GetX() + targetRect.GetWidth() / 2; float centerY = targetRect.GetY() + targetRect.GetHeight() / 2; // 应用旋转变换矩阵:先平移到旋转中心,执行旋转,再平移回原位置 gfx.ConcatMatrix( (float)Math.Cos(radians), (float)Math.Sin(radians), -(float)Math.Sin(radians), (float)Math.Cos(radians), centerX - centerX * (float)Math.Cos(radians) + centerY * (float)Math.Sin(radians), centerY - centerX * (float)Math.Sin(radians) - centerY * (float)Math.Cos(radians) ); // 将复用的XObject放入目标矩形(此时已应用旋转) gfx.AddXObjectFittedIntoRectangle(imageXObject, targetRect); // 恢复画布状态,回到变换前的状态 gfx.RestoreState();
调整旋转中心
如果需要围绕其他点旋转(比如矩形左下角),只需修改centerX和centerY的值:
// 围绕矩形左下角旋转 float centerX = targetRect.GetX(); float centerY = targetRect.GetY();
原理说明
通过ConcatMatrix修改画布的变换矩阵,相当于给后续的绘制操作添加了旋转效果,而XObject本身并未被修改,因此可以多次复用同一个XObject,同时每次绘制都有独立的旋转角度。这种方式既保证了图片资源的复用(仅加载一次),又实现了差异化的旋转需求。
内容的提问来源于stack exchange,提问作者Valentín Elizondo Nevares
相关产品推荐
相关产品推荐

