如何绕中心旋转QPixmap并适配新尺寸以避免图像裁切?
解决QPixmap旋转后避免裁切的问题
你之前找到的示例之所以会出现裁切,核心问题是直接复用了原图像的尺寸——但只要不是0/180度这类特殊角度,旋转后的图像外接尺寸肯定会比原尺寸大。下面是完整的实现方案,能完美适配旋转后的图像,完全避免裁切:
步骤1:先算出旋转后的最小外接尺寸
这是最关键的一步,我们需要通过QTransform计算原始图像旋转指定角度后的实际占用空间:
// 假设你已经有了原始QPixmap QPixmap original(20, 100); // 设定要旋转的角度(比如45度) double rotationAngle = 45.0; // 创建旋转变换对象 QTransform transform; transform.rotate(rotationAngle); // 计算原始图像矩形旋转后的外接矩形 QRectF originalRect = original.rect(); QRectF rotatedBounds = transform.mapRect(originalRect);
步骤2:创建适配尺寸的新QPixmap
用计算出来的rotatedBounds尺寸创建新的QPixmap,记得根据需求设置背景(比如透明或纯色):
// 把浮点尺寸转为整数尺寸,创建足够大的新Pixmap QPixmap rotatedPixmap(rotatedBounds.size().toSize()); // 如果需要透明背景就用这个,不透明的话可以换成Qt::white之类的颜色 rotatedPixmap.fill(Qt::transparent);
步骤3:绕中心绘制旋转后的图像
接下来用QPainter把原始图像绘制到新Pixmap上,重点是让图像中心对齐,绕中心旋转:
QPainter painter(&rotatedPixmap); // 把绘制原点移到新图像的中心 painter.translate(rotatedPixmap.width() / 2, rotatedPixmap.height() / 2); // 执行旋转操作 painter.rotate(rotationAngle); // 将原始图像绘制到相对于中心的偏移位置(保证原图像中心和新图像中心重合) painter.drawPixmap(-original.width() / 2, -original.height() / 2, original); // 结束绘制 painter.end();
完整可复用函数
把上面的步骤整合起来,就是一个可以直接调用的工具函数:
QPixmap rotatePixmapWithoutCrop(const QPixmap& original, double angle) { if (original.isNull()) return QPixmap(); QTransform transform; transform.rotate(angle); QRectF rotatedBounds = transform.mapRect(original.rect()); QPixmap rotatedPixmap(rotatedBounds.size().toSize()); rotatedPixmap.fill(Qt::transparent); QPainter painter(&rotatedPixmap); // 可选:开启平滑渲染,让旋转后的图像边缘更细腻 painter.setRenderHint(QPainter::SmoothPixmapTransform); painter.translate(rotatedPixmap.width() / 2, rotatedPixmap.height() / 2); painter.rotate(angle); painter.drawPixmap(-original.width() / 2, -original.height() / 2, original); painter.end(); return rotatedPixmap; }
额外说明
- 之前的示例裁切的原因:它直接用原图像的
size()创建新Pixmap,旋转后超出原尺寸的部分自然被切掉了; SmoothPixmapTransform是可选配置,适合对图像清晰度有要求的场景;- 如果你的图像是不透明类型,可以把
fill(Qt::transparent)换成fill(Qt::white)或你需要的背景色。
内容的提问来源于stack exchange,提问作者Griffort
相关产品推荐
相关产品推荐

