我有一个倒y轴的场景。除了QImages之外,所有内容都被正确绘制。
我使用drawIage()
作为:
QRectF aWorldRect = ...
QRectF anImageRect = QRectF(0, 0, theQImage.width(), theQImage.height())
thePainter->drawImage(aWorldRect, theQImage, anImageRect;
我在应该显示图像的外部(到顶部)获得未定义的图形。这是正常的,因为y轴是反转的。所以我期望这样的事情可以解决这个问题:
QRectF anImageRect = QRectF(0, 0, imgWidth, -imgHeight)
它具有相同的效果。如果我在调用aWorldRect = aWorldRect.noralized()
之前drawImage()
,我会将图片放入正确的矩形,但是镜像,所以我做了aQImage = aQImage.mirrored()
。现在图像正确显示在正确的矩形
我认为这是一种我不喜欢的解决方法。那么,有人可以告诉我应该怎样做以正确的方式显示图像吗?
更新 在这里,我提出了一个可以编译的问题的最小样本:
更新2014-04-09 10:05 EET 使用解决方法
更新了示例代码以使其真正有效#include <QtGui>
const int WIDTH = 640;
const int HEIGHT = 480;
class View : public QGraphicsView
{
protected:
void drawBackground(QPainter *p, const QRectF & rect)
{
QImage img = QImage("/usr/share/backgrounds/images/stone_bird.jpg"); // or any other
/* The next three lines makes everything displayed correctly but
should be considered a workaround */
/* I ignore the rect that is passed to the function on purpose */
QRectF imageRect = QRectF(QPointF(0, 0), QPointF(img.width(), img.height()));
QRectF theSceneRect = sceneRect().normalized();
p->drawImage(theSceneRect, img.mirrored(), imageRect);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
View w;
/* I don't want to change the code below */
w.setScene(new QGraphicsScene(QRectF(QPointF(0, HEIGHT), QPointF(WIDTH, 0))));
w.scale(1, -1);
w.scene()->addLine(0, HEIGHT, WIDTH, 0);
w.showMaximized();
return a.exec();
}
答案 0 :(得分:2)
反转Y坐标值的方法是正确的,但实施是错误的。
QRectF的文档显示它需要(x,y,width,height)。将高度视为负面是没有意义的。而是尝试使用 topLeft 和 bottomRight 的其他构造函数。
QRectF anImageRect(QPointF(0.0f, -imgHeight), QPointF(imageWidth, 0.0f));
修改强>
看起来像线,弧等唯一的图形会受到您在视图上设置的比例(1,-1)变换的影响。由于比例设定,drawImage
继续呈现倒置。简单的解决方法是将比例设置回(1,-1)。这是更新后的代码:
void drawBackground(QPainter *p, const QRectF & rect)
{
QImage img = QImage("/usr/share/backgrounds/images/stone_bird.jpg");
// backup the current transform set (which has the earlier scale of (1, -1))
const QTransform oldTransform = p->transform();
// set the transform back to identity to make the Y axis go from top to bottom
p->setTransform(QTransform());
// draw
QRectF theSceneRect = sceneRect().normalized();
p->drawImage(theSceneRect, img);
// revert back to the earlier transform
p->setTransform(oldTransform);
}
答案 1 :(得分:1)
更新于2014-04-14 14:35 EET
我最终可以通过替换两行来解决问题
QRectF theSceneRect = sceneRect().normalized();
p->drawImage(theSceneRect, img.mirrored(), imageRect);
我的问题
QRectF theSceneRect = sceneRect(); // Not normalized. It is no more workaround :)
qreal x = theSceneRect.x();
qreal y = theSceneRect.y();
qreal w = theSceneRect.width();
qreal h = theSceneRect.height();
qreal sx = imageRect.x();
qreal sy = imageRect.y();
qreal sw = imageRect.width();
qreal sh = imageRect.height();
p->translate(x, y);
p->scale(w / sw, h / sh);
p->setBackgroundMode(Qt::TransparentMode);
p->setRenderHint(QPainter::Antialiasing, p->renderHints() &
QPainter::SmoothPixmapTransform);
QBrush brush(img);
p->setBrush(brush);
p->setPen(Qt::NoPen);
p->setBrushOrigin(QPointF(-sx, -sy));
p->drawRect(QRectF(0, 0, sw, sh));
p->restore();
这受到QPainter::drawImage()
的实现的启发,由于许多 if 语句处理宽度或高度为负值的矩形,因此在这种情况下不可靠。
如果我在另一个函数中创建解决方案会更好,但我保持这种方式与我的问题中的代码更兼容。