(C++) How to StretchDraw an image?

February 24, 2017 · View on GitHub

 

 

 

 

 

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