放大缩小后的QPixmap:无法恢复原始大小

问题描述 投票:0回答:2

我正在制作一个应用程序,我需要在图片上方绘制图形(即矩形)并调整整个场景的大小。我正在使用

QGraphicsView
QGraphicsScene
。我不明白为什么,但是当我使用
fitIntoView()
时,我无法在图片上绘制图形(它们可能是在图片后面或边界之外绘制的)。

现在我使用

QPixmap.scaled()
使图像适合
QGraphicsScene
。它工作得很好,除非我需要显示大图像然后放大它。因为我缩放了图像以适应,它变得更小,当我调用
QGraphicsView.scale()
时,图像缩放为小图像,我找不到一种方法将图像“缩小”到原始大小。

在代码的缩放部分,我尝试用其未缩放的副本替换像素图,但我无法以与我的数字缩放相同的比例缩放它。 任何帮助将不胜感激!


这里我加载图像并缩放它

QPixmap pix;
pix = pixmap->scaled(wid, hei,Qt::KeepAspectRatio, Qt::SmoothTransformation);
scn = new QGraphicsScene(pw);
pw->setScene(scn);
p = new QGraphicsPixmapItem(pix);
p->setPixmap(pix);
scn->addItem(p);

我画的人物是这样的

rect = new QGraphicsRectItem(x,y,w,h);
rect->setPen(QPen(getColor(), 1, Qt::SolidLine, Qt::FlatCap));
scn->addItem(rect);

这就是我如何缩放

pw->scale(scaleFactor_,scaleFactor_);

更新: 现在我有一个

QWidget
,顶部有某种工具栏,其余的可用空间充满了自定义
QGraphicsView
。这是一个用于抓取鼠标事件的派生类,除了事件处理程序的重写之外什么也没有。我在小部件的构造函数中添加 PainterGraphicsView:

pw = new PainterGraphicsView();
ui->gridLayout_3->addWidget(pw);

每次加载新图像时,我都会重新创建场景:

scn = new QGraphicsScene(pw);
pw->setScene(scn);
QRect r = QRect(0,0, pw->width()-5, pw->height()-5);
scn->setSceneRect(r);

加载图像后,我可以在其上绘制图形,它看起来像这样:

缩放后的内容如下所示:

如您所见,图形与像素图一起缩放,这正是我需要它的工作方式。我唯一需要解决的是缩放像素图的低质量。正如我已经说过的,我尝试在 ZoomIn 方法中用原始像素图替换像素图,但我无法保存图形的位置。

void DrawerWidget::on_btZoom_clicked()
{
    p->setPixmap(pix); //p is QGraphicsPixmapItem, pix is an original pixmap
    p->setScale(0.5); //how can I scale the pixmap together with figures?? How to calculate the required scale?
    pw->scale(scaleFactor_,scaleFactor_);
}


更新2:

对我的绘图方法的简短说明:(虽然我个人不认为这是问题,但我感兴趣的是有没有一种方法可以使用 setScale() 缩放 QGraphicsPixmapItem 以适应 QGraphicsView 大小)

我从鼠标事件参数中获取

start_
end_
坐标
(QMouseEvent *e)

 end_=pw->mapToScene(e->pos());
 start_=pw->mapToScene(e->pos());

我在鼠标按下时添加了图形:

rect = new QGraphicsRectItem(start_.x(),start_.y(),1,1);
scn->addItem(rect);

我在鼠标移动时重新绘制图形

rect->setRect(Graphics::GetFigure(start_.x(),start_.y(),end_.x(),end_.y()));

GetFigure是一个计算图形矩形的方法,这里是它的主要部分:

 static QRectF GetFigure(double startX, double startY, double finalX, double finalY)
    {
      QRectF shape;
      shape.setX(startX);
      shape.setY(startY);
      shape.setWidth(qFabs(finalX - startX));
      shape.setHeight(qFabs(finalY - startY));
      return shape;
   }
qt qgraphicsview qgraphicsscene qpixmap
2个回答
5
投票

缩放操作具有破坏性,一旦缩小,最终得到的数据会比开始时少。

如果您希望能够恢复原始大小,请保留原始像素图的副本。

您可以从原始的、未缩放的像素图创建

QGraphicsPixmapItem
,然后使用
QGraphicsPixmapItem::setScale(qreal)
更改关卡图形项的大小,而不是关卡像素图数据的大小。这样缩放不应该具有破坏性,并且如果将其放大到原始尺寸,也不应该损失质量。

如果您想缩放多个项目(并且不遇到不同的转换原点问题),您有几个选择:

  • 缩放整个视图 - 这将缩放所有内容
  • 将项目添加为父项目的子项目,然后缩放父项目也会缩放其子项目

项目转换从父级到子级累积

项目全部重新设置为组的父级,并且它们的位置和 转换映射到组


1
投票

我认为你的问题是你将场景矩形设置为

QGraphicsView
矩形。这是不正确的,因为窗口参考系统与场景参考系统不同。 您不需要设置场景矩形,因为当您添加一些项目时场景矩形会自动增长。如果要将场景矩形限制为像素图矩形,可以将场景矩形设置为
QPixampItem
边界矩形。

您不需要缩放原始像素图。要缩放视图,只需拨打

QGrapicsView::scale
。您还可以调用
QGrapicsView::fitInView
使图像适合视图。

如果您需要添加一些用户绘制的矩形(即在窗口坐标中),您可以使用

QGraphiscView::mapToScene
将窗口坐标映射到场景坐标

我建议阅读有关参考系统的文档:图形视图坐标系

© www.soinside.com 2019 - 2024. All rights reserved.