Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) Qt How to StretchDraw an image?

 

How to StretchDraw an image? is a QT FAQ especially encountered during games.

 

There are three ways to stretchdraw an image:

  1. rectangular blocky stretchdraw, like this image (png)
  2. square blocky stretchdraw, like this image (png)
  3. smooth stretchdraw, like this image (png)

 

 

 

 

 

 

Rectangular blocky stretchdraw

 

To perform a rectangular blocky stretchdraw, like this image (png), obtain a QPainter from a QWidget.

 

 

 

 

 

dialogblockyrect.h

 

#ifndef DIALOGBLOCKYRECT_H
#define DIALOGBLOCKYRECT_H

#include <boost/shared_ptr.hpp>
#include <QDialog>

struct QPaintEvent;
struct QTimer;

namespace Ui {
  class DialogBlockyRect;
}

class DialogBlockyRect : public QDialog
{
  Q_OBJECT

public:
  explicit DialogBlockyRect(QWidget *parent = 0);
  ~DialogBlockyRect();

protected:
  void changeEvent(QEvent *e);

private:
  Ui::DialogBlockyRect *ui;
  boost::shared_ptr<QTimer> m_timer;
  void paintEvent(QPaintEvent*);

private slots:
  void onTimer();
};

#endif // DIALOGBLOCKYRECT_H

 

 

 

 

 

dialogblockyrect.cpp

 

#include <cstdlib>

#include <QPainter>
#include <QPaintEvent>
#include <QTimer>

#include "dialogblockyrect.h"
#include "ui_dialogblockyrect.h"

DialogBlockyRect::DialogBlockyRect(QWidget *parent)
  : QDialog(parent,Qt::Window),
    ui(new Ui::DialogBlockyRect),
    m_timer(new QTimer)
{
  ui->setupUi(this);

  //Connect and start the timer
  QObject::connect(m_timer.get(),SIGNAL(timeout()),this,SLOT(onTimer()));
  m_timer->start(1000);
}

DialogBlockyRect::~DialogBlockyRect()
{
  delete ui;
}

void DialogBlockyRect::changeEvent(QEvent *e)
{
  QDialog::changeEvent(e);
  switch (e->type()) {
  case QEvent::LanguageChange:
    ui->retranslateUi(this);
    break;
  default:
    break;
  }
}

void DialogBlockyRect::paintEvent(QPaintEvent*)
{
  QPainter painter(this);

  QPixmap pixmap(5,5);
  QImage image = pixmap.toImage();
  const int maxy = image.height();
  const int maxx = image.width();
  for (int y=0; y!=maxy; ++y)
  {
    for (int x=0; x!=maxx; ++x)
    {
      image.setPixel(
        QPoint(x,y),
        QColor(std::rand() % 255,
               std::rand() % 255,
               std::rand() % 255).rgb());
    }
  }
  pixmap = pixmap.fromImage(image);
  painter.drawPixmap(ui->widget->rect(),pixmap);
}

void DialogBlockyRect::onTimer()
{
  repaint();
}

 

 

 

 

 

Square blocky stretchdraw

 

To perform a square blocky stretchdraw, like this image (png), the visual widget QGraphicsView is used. A (blocky) rescaled QGraphicsPixmapItem does the trick.

 

 

 

 

 

dialogblockysquare.h

 

#ifndef DialogBlocky_H
#define DialogBlocky_H

#include <boost/shared_ptr.hpp>
#include <QDialog>
struct QGraphicsPixmapItem ;
struct QGraphicsScene;
struct QTimer;

namespace Ui {
    class DialogBlockySquare;
}

class DialogBlockySquare : public QDialog
{
    Q_OBJECT

public:
    explicit DialogBlockySquare(QWidget *parent = 0);
    ~DialogBlockySquare();

protected:
    void changeEvent(QEvent *e);
    void resizeEvent(QResizeEvent*);
private:
    Ui::DialogBlockySquare *ui;
    boost::shared_ptr<QGraphicsScene> m_scene;
    boost::shared_ptr<QGraphicsPixmapItem> m_sprite;
    boost::shared_ptr<QTimer> m_timer;
private slots:
  void onTimer();
};

#endif // DialogBlocky_H

 

 

 

 

 

dialogblockysquare.cpp

 

#include <iostream>
#include <boost/foreach.hpp>
#include <QColor>
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include <QPixmap>
#include <QPoint>
#include <QTimer>

#include "dialogblockysquare.h"
#include "ui_dialogblockysquare.h"

DialogBlockySquare::DialogBlockySquare(QWidget *parent) :
  QDialog(parent,Qt::Window), //Allow resize of dialog
  ui(new Ui::DialogBlockySquare),
  m_scene(new QGraphicsScene),
  m_sprite(new QGraphicsPixmapItem),
  m_timer(new QTimer)
{
  ui->setupUi(this);

  //Create a 5x5 (nonvisual) sprite
  m_sprite->setPixmap(QPixmap(5,5));
  //Add the sprite to the (nonvisual) scene
  m_scene->addItem(m_sprite.get());
  //Add the scene to the (visual) graphicsscene
  ui->graphicsView->setScene(m_scene.get());

  //Create a timer to change the graphicsview
  QObject::connect(m_timer.get(),SIGNAL(timeout()),this,SLOT(onTimer()));
  m_timer->start(1000);
  onTimer();
}

DialogBlockySquare::~DialogBlockySquare()
{
  delete ui;
}

void DialogBlockySquare::changeEvent(QEvent *e)
{
  QDialog::changeEvent(e);
  switch (e->type()) {
  case QEvent::LanguageChange:
    ui->retranslateUi(this);
    break;
  default:
      break;
  }
}

void DialogBlockySquare::resizeEvent(QResizeEvent*)
{
  //Rescale the blocky image to fit the graphicsview
  const double scale_x
    = static_cast<double>(ui->graphicsView->width())
    / static_cast<double>(m_sprite->pixmap().width());
  const double scale_y
    = static_cast<double>(ui->graphicsView->height())
    / static_cast<double>(m_sprite->pixmap().height());
  m_sprite->setScale(std::min(scale_x,scale_y));
}

void DialogBlockySquare::onTimer()
{
  //Draw a new blocky image
  QImage image = m_sprite->pixmap().toImage();
  const int maxy = image.height();
  const int maxx = image.width();
  for (int y=0; y!=maxy; ++y)
  {
    for (int x=0; x!=maxx; ++x)
    {
      image.setPixel(QPoint(x,y),
        QColor(std::rand() % 255,
        std::rand() % 255,
        std::rand() % 255).rgb());
    }
  }
  m_sprite->setPixmap(m_sprite->pixmap().fromImage(image));
}

 

 

 

 

 

Smooth stretchdraw

 

To perform a smooth stretchdraw, like this image (png), the visual widget QLabel is used.

 

 

 

 

 

dialogsmooth.h

 

#ifndef DialogSmooth_H
#define DialogSmooth_H

#include <boost/shared_ptr.hpp>
#include <QDialog>
struct QTimer;

namespace Ui {
  class DialogSmooth;
}

class DialogSmooth : public QDialog
{
  Q_OBJECT

public:
  explicit DialogSmooth(QWidget *parent = 0);
  ~DialogSmooth();

protected:
  void changeEvent(QEvent *e);

private:
  Ui::DialogSmooth *ui;
  boost::shared_ptr<QTimer> m_timer;
private slots:
  void onTimer();
};

#endif // DialogSmooth_H

 

 

 

 

 

dialogsmooth.cpp

 

#include <iostream>
#include <boost/foreach.hpp>
#include <QColor>
#include <QPoint>
#include <QTimer>
#include "dialogsmooth.h"
#include "ui_dialogsmooth.h"

DialogSmooth::DialogSmooth(QWidget *parent) :
  QDialog(parent,Qt::Window), //Allow resize of dialog
  ui(new Ui::DialogSmooth),
  m_timer(new QTimer)
{
  ui->setupUi(this);

  //Create a 5x5 image
  ui->label->setPixmap(QPixmap(5,5));
  QObject::connect(m_timer.get(),SIGNAL(timeout()),this,SLOT(onTimer()));
  onTimer();
  m_timer->start(1000);
}

DialogSmooth::~DialogSmooth()
{
  delete ui;
}

void DialogSmooth::changeEvent(QEvent *e)
{
  QDialog::changeEvent(e);
  switch (e->type()) {
  case QEvent::LanguageChange:
    ui->retranslateUi(this);
    break;
  default:
    break;
  }
}

void DialogSmooth::onTimer()
{
  //Draw a new smooth image
  QImage image = ui->label->pixmap()->toImage();
  const int maxy = image.height();
  const int maxx = image.width();
  for (int y=0; y!=maxy; ++y)
  {
    for (int x=0; x!=maxx; ++x)
    {
      image.setPixel(QPoint(x,y),
        QColor(std::rand() % 255,
        std::rand() % 255,
        std::rand() % 255).rgb());
    }
  }
  ui->label->setPixmap(ui->label->pixmap()->fromImage(image));
}

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict