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

时间:2016-02-26 12:48:12

标签: qt qgraphicsview qgraphicsscene qpixmap

我正在创建一个应用程序,我需要在图片上方绘制图形(即矩形)并调整整个场景的大小。我正在使用QGraphicsViewQGraphicsScene。我无法弄清楚为什么,但是当我使用fitIntoView()时,我无法在图片顶部绘制数字(它们可能是在图片后面或边界之外绘制的)。

现在我使用QPixmap.scaled()使图片适合QGraphicsScene。它工作正常,除非我需要显示一个大图像,然后放大。因为我缩放图像以适应,它变得更小,当我调用QGraphicsView.scale()时,图像缩小为小,我可以'找到一种方法来缩减"图像为原始大小。

在代码的缩放部分,我尝试用不缩放的副本替换pixmap,但是我不能用与我的缩放比例相同的比例缩放它。 任何帮助将不胜感激!

这里我加载图像并缩放它

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);

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

enter image description here

缩放内容如下所示:

enter image description here

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

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_);
}

enter image description here

更新2:

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

我从鼠标事件参数start_

获取end_(QMouseEvent *e)坐标
 end_=pw->mapToScene(e->pos());
 start_=pw->mapToScene(e->pos());

我在mousepress上添加了这个数字:

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;
   }

2 个答案:

答案 0 :(得分:4)

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

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

您可以从原始的非缩放像素图创建QGraphicsPixmapItem,然后使用QGraphicsPixmapItem::setScale(qreal)更改级别图形项目的大小,而不是级别像素图数据。这种方式缩放不应具有破坏性,如果将其缩放到原始大小,则不应该失去质量。

如果您想缩放多个项目(而不是遇到不同的转换起源问题),您可以选择以下几个选项:

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

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

  • 使用createItemGroup()
  • 将项目添加到组中
  

这些项目全部归属于该组,以及他们的位置和   转换映射到组

答案 1 :(得分:1)

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

您不需要缩放原始像素图。要缩放视图,只需致电QGrapicsView::scale即可。您也可以致电QGrapicsView::fitInView以使图片适合视图。

如果您需要添加用户绘制的一些片段(即在窗口坐标中),您可以使用QGraphiscView::mapToScene将窗口坐标映射到场景坐标

我建议阅读有关参考系统的文档:The Graphics View Coordinate System