You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iText中SetRotationAngle不生效:单图片多引用旋转问题

解决iText中复用图片并设置不同旋转角度的问题

问题原因

你之前的代码无法实现旋转的核心原因有两个:

  1. SetRotationAngle是修改Image实例的属性,生成XObject后,旋转参数会固化到XObject中,复用该XObject时所有引用都会使用同一旋转角度,无法实现差异化旋转。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:42:09