3

我面临一个可能很容易解决的问题,但我没有做对:我有两个 QImage,一个固定大小的背景图像imgBg和第二个 QImage imgFg,应该使用仿射变换进行变换,然后在上绘制(和剪辑)背景图像。

仿射变换如下:

  • 围绕原点缩放图像(统一缩放)
  • 围绕原点旋转图像
  • 将前景图像平移到背景图像上的某个参考位置,使前景图像中心在参考位置上。

这是我到目前为止所做的:

// Setup transform
QTransform trans;
trans.translate(-imgFg.width()/2, -imgFg.height()/2); // move center of image to origin
trans.scale(scaleFac, scaleFac);
trans.rotate(angleDegrees);
trans.translate(imgFg.width()/2, imgFg.height()/2);

// Transform foreground image
imgFg = imgFg.transformed(trans);

// Paint on background image
QPointF referencePos(imgBg.width()/3, imgBg.height()/2); // some reference position
QPainter painter(&imgBg);
painter.drawImage(referencePos - QPointF(imgFg.width()/2, imgFg.height()/2), imgFg);

只要我只更改参考位置,一切正常。使用缩放和/或旋转时,图像也会正确缩放和旋转,但未放置在正确的位置(前景的图像中心与参考点不匹配)。转换管道有问题吗?我犯错了吗?

4

1 回答 1

3

您需要颠倒您在QTransform. 顺序必须与直觉思维相反。这与线性代数中变换矩阵的矩阵乘法有关。(变换矩阵的基础改变......)问题是变换适用于源坐标系,这有点不直观。

所以请记住:每当您想应用多个转换时,请按照您对图像所做的相反顺序进行。

有关示例,请参见QTransform 文档中的示例代码:

将文本缩放到一半宽度,然后顺时针旋转 45 度,然后将其原点移动到 (50, 50):

在此处输入图像描述

QTransform transform;
transform.translate(50, 50);
transform.rotate(45);
transform.scale(0.5, 1.0);

另一个问题是您应该通过考虑缩放因子将图像转换回其原点(感谢 Mat 在问题评论中指出这一点)。

应用于您的代码片段(从下到上阅读直观的操作顺序):

// Setup transform
QTransform trans;
trans.translate(imgFg.width()*scaleFac/2, imgFg.height()*scaleFac/2);
trans.rotate(angleDegrees);
trans.scale(scaleFac, scaleFac);
trans.translate(-imgFg.width()/2, -imgFg.height()/2);

最后但并非最不重要的一点是,您希望将图像的中心作为新的原点(参考点),因此您不应该向后平移(现在是第一个操作;在您的代码中是最后一个操作)。然后只需在参考点绘制图像,而不是添加另一个 size/2。此外,您不应将变换应用于图像然后绘制此图像;至少它不是很好的风格。只需将变换应用于画家,然后再取消应用。

QTransform trans;
trans.scale(scaleFac, scaleFac);
trans.rotate(angleDegrees);
trans.translate(imgFg.width()/2,imgFg.height()/2);

// Save old transform (only needed if you use other transformations)
const QTransform &oldTrans = painter.transform();
// Apply new transform
painter.setTransform(trans);
// Paint image at reference point
painter.drawImage(referencePoint, imgFg);
// Restore transform
painter.setTransform(oldTrans);
于 2012-05-27T12:46:04.783 回答