下调时,GraphicsView fitInView()非常像素化的结果

时间:2014-11-07 12:23:47

标签: image qt qgraphicsview qgraphicsscene qpixmap

我到处搜索,经过2天的尝试,我找不到任何解决方案。

问题:

我正在使用" Fit Image to View"进行图像查看。特征。我在我的GraphicsView中加载了一张3000+像素的照片(这是一个相当小的场景),滚动条似乎很好。当我点击我的btnFitView并执行:

ui->graphicsView->fitInView(scene->sceneRect(),Qt::KeepAspectRatio);

这是缩小版权吗?在fitInView()之后,所有行都是像素化的。它看起来像是锯在图像上的线条。

例如:汽车的图像有线条,短信的图像(字母质量非常差)。

我的代码示例:

// select file, load image in view
QString strFilePath = QFileDialog::getOpenFileName(
            this,
            tr("Open File"),
             "/home",
            tr("Images (*.png *.jpg)"));

imageObject = new QImage();
imageObject->load(strFilePath);
image = QPixmap::fromImage(*imageObject);

scene = new QGraphicsScene(this);
scene->addPixmap(image);
scene->setSceneRect(image.rect());
ui->graphicsView->setScene(scene);


// on_btnFitView_Clicked() :
ui->graphicsView->fitInView(scene->sceneRect(),Qt::KeepAspectRatio);

就在fitInView()之前,尺寸为:

qDebug()<<"sceneRect = "<< scene->sceneRect();
qDebug()<<"viewRect = " << ui->graphicsView->rect();

sceneRect =  QRectF(0,0 1000x750)
viewRect =   QRect(0,0 733x415)  

如果有必要,我可以上传原始加载图像的截图并安装在视图中吗?

我这样做对吗?似乎Web上的所有示例都使用fitInView进行自动拟合。我应该在pixmap上使用其他一些操作吗?

// LOAD IMAGE
bool ImgViewer::loadImage(const QString &strImagePath)
{
  m_image = new QImage(strImagePath);
  if(m_image->isNull()){
    return false;
  }
  clearView();

  m_pixmap = QPixmap::fromImage(*m_image);     
  m_pixmapItem = m_scene->addPixmap(m_pixmap); 
  m_scene->setSceneRect(m_pixmap.rect());      
  this->centerOn(m_pixmapItem);

  // preserve fitView if active
  if(m_IsFitInView)
      fitView();

  return true;
}

// TOGGLED FUNCTIONS
void ImgViewer::fitView()
{
    if(m_image->isNull())
      return;

    this->resetTransform();
    QPixmap px = m_pixmap; // use local pixmap (not original) otherwise image is blurred after scaling the same image multiple times
    px = px.scaled(QSize(this->width(),this->height()),Qt::KeepAspectRatio,Qt::SmoothTransformation);
    m_pixmapItem->setPixmap(px);
    m_scene->setSceneRect(px.rect());
}
void ImgViewer::originalSize()
{
    if(m_image->isNull())
       return;

    this->resetTransform();
    m_pixmap = m_pixmap.scaled(QSize(m_image.width(),m_image.height()),Qt::KeepAspectRatio,Qt::SmoothTransformation); 
    m_pixmapItem->setPixmap(m_pixmap);
    m_scene->setSceneRect(m_pixmap.rect());
    this->centerOn(m_pixmapItem); //ensure item is centered in the view.
}

在降低收缩时,这会产生良好的质量。调用这两个函数后,这里有一些统计数据:

//    "originalSize()"  : IMAGE SIZE =   (1152, 2048)
//    "originalSize()"  : PIXMAP SIZE =  (1152, 2048)
//    "originalSize()"  : VIEW SIZE =    (698, 499)
//    "originalSize()"  : SCENE SIZE =   (1152, 2048)

//    "fitView()"   : IMAGE SIZE =   (1152, 2048)
//    "fitView()"   : PIXMAP SIZE =  (1152, 2048)
//    "fitView()"   : VIEW SIZE =    (698, 499) 
//    "fitView()"   : SCENE SIZE =   (280, 499)

现在有一个问题,在调用fitView()之后看看场景的大小?小多了。

如果fitView()被激活,我现在在wheelEvent(zoomIn / zoomOut)上缩放图像,使用视图缩放功能:scale(factor,factor); ..产生可怕的结果。 在场景大小等于图像大小的originalSize()中不会发生这种情况。

1 个答案:

答案 0 :(得分:1)

将视图视为进入场景的窗口。

大幅移动视图(放大或缩小)可能会创建看起来不太好的图像。视图正在远离场景并尽力渲染图像,而不是缩放图像,而是图像没有缩放,只是在场景中进行了变换。

不是使用QGraphicsView :: fitInView,而是将主图像保留在内存中并使用QPixamp::scaled创建图像的缩放版本,每次选择FitInView,或者用户放大/缩小。然后使用setPixmap在QGraphicsPixmapItem上设置此QPixmap。

您可能还想考虑删除滚动条并允许用户在屏幕上拖动图像,这在我看来提供了更好的用户界面;当然,这取决于你的要求。