Exemple #1
0
// really generate the cache
void ImageView::generateCache() {
  // disable the one-shot timer
  cacheTimer_->deleteLater();
  cacheTimer_ = nullptr;

  if(!imageItem_ || image_.isNull()) return;

  // generate a cache for "the visible part" of the scaled image
  // rectangle of the whole image in viewport coordinate
  QRect viewportImageRect = sceneToViewport(imageItem_->rect());
  // rect of the image area that's visible in the viewport (in viewport coordinate)
  cachedRect_ = viewportImageRect.intersected(viewport()->rect());

  // convert to the coordinate of the original image
  cachedSceneRect_ = viewportToScene(cachedRect_);
  // create a sub image of the visible without real data copy
  // Reference: http://stackoverflow.com/questions/12681554/dividing-qimage-to-smaller-pieces
  QRect subRect = image_.rect().intersected(cachedSceneRect_);
  const uchar* bits = image_.constBits();
  unsigned int offset = subRect.x() * image_.depth() / 8 + subRect.y() * image_.bytesPerLine();
  QImage subImage = QImage(bits + offset, subRect.width(), subRect.height(), image_.bytesPerLine(), image_.format());

  // If the original image has a color table, also use it for the subImage
  QVector<QRgb> colorTable = image_.colorTable();
  if (!colorTable.empty())
    subImage.setColorTable(colorTable);

  // QImage scaled = subImage.scaled(subRect.width() * scaleFactor_, subRect.height() * scaleFactor_, Qt::KeepAspectRatio, Qt::SmoothTransformation);
  QImage scaled = subImage.scaled(cachedRect_.width(), cachedRect_.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation);

  // convert the cached scaled image to pixmap
  cachedPixmap_ = QPixmap::fromImage(scaled);
  viewport()->update();
}
Exemple #2
0
void ImageView::paintEvent(QPaintEvent* event) {
  // if the image is scaled and we have a high quality cached image
  if(imageItem_ && scaleFactor_ != 1.0 && !cachedPixmap_.isNull()) {
    // rectangle of the whole image in viewport coordinate
    QRect viewportImageRect = sceneToViewport(imageItem_->rect());
    // the visible part of the image.
    QRect desiredCachedRect = viewportToScene(viewportImageRect.intersected(viewport()->rect()));
    // check if the cached area is what we need and if the cache is out of date
    if(cachedSceneRect_ == desiredCachedRect) {
      // rect of the image area that needs repaint, in viewport coordinate
      QRect repaintImageRect = viewportImageRect.intersected(event->rect());
      // see if the part asking for repaint is contained by our cache.
      if(cachedRect_.contains(repaintImageRect)) {
        QPainter painter(viewport());
        painter.fillRect(event->rect(), backgroundBrush());
        painter.drawPixmap(repaintImageRect, cachedPixmap_);
        return;
      }
    }
  }
  if(!image_.isNull()) { // we don't have a cache yet or it's out of date already, generate one
    queueGenerateCache();
  }
  QGraphicsView::paintEvent(event);
}
Exemple #3
0
void ImageView::generateCache()
{
  delete m_cacheTimer;
  m_cacheTimer = 0;

  if (!m_item)
    return;

  m_cachedRect      = sceneToViewport(m_item->rect()).intersected(viewport()->rect());
  m_cachedSceneRect = viewportToScene(m_cachedRect);
  const QRect subRect = m_image.rect().intersected(m_cachedSceneRect);

# if QT_VERSION >= 0x040700
  const uchar* bits = m_image.constBits();
# else
  const uchar* bits = m_image.bits();
# endif

  const unsigned int offset = subRect.x() * m_image.depth() / 8 + subRect.y() * m_image.bytesPerLine();

  const QImage subImage = QImage(bits + offset, subRect.width(), subRect.height(), m_image.bytesPerLine(), m_image.format());

  ScaleRunnable *runnable = new ScaleRunnable(subImage.copy(), m_cachedRect.size());
  connect(runnable, SIGNAL(finished(QImage)), SLOT(onFinished(QImage)));

  QThreadPool::globalInstance()->start(runnable);
}
Exemple #4
0
Rect2 Graphic::Renderer::viewportToScene(Rect2 const& rect) const {
    if (_scene == NULL)
        throw new Graphic::Exception("Tried to transform coords but no scene was specified");
    Vec2 viewport = getViewportSize();
    Vec2 scene = _scene->getViewport();
    Vec2 newPos = viewportToScene(rect.pos);
    Vec2 newSize = rect.size / viewport * scene;
    newPos.y -= newSize.y;
    Rect2 newRect(newPos, Vec2(newSize));
    return newRect;
}
Exemple #5
0
void ImageView::paintEvent(QPaintEvent* event)
{
  if (m_item && m_scaleFactor != 1.0 && !m_cachedPixmap.isNull()) {
    const QRect viewportImageRect = sceneToViewport(m_item->rect());
    const QRect desiredCachedRect = viewportToScene(viewportImageRect.intersected(viewport()->rect()));

    if (m_cachedSceneRect == desiredCachedRect) {
      const QRect repaintImageRect = viewportImageRect.intersected(event->rect());
      if (m_cachedRect.contains(repaintImageRect)) {
        QPainter painter(viewport());
        painter.fillRect(event->rect(), backgroundBrush());
        painter.drawPixmap(repaintImageRect, m_cachedPixmap);
        return;
      }
    }
  }

  if (!m_image.isNull())
    queueGenerateCache();

  QGraphicsView::paintEvent(event);
}