Go back to Richel Bilderbeek's homepage.
Go back to Richel Bilderbeek's C++ page.
How to StretchDraw an image? is a QT FAQ especially encountered during games.
There are three ways to stretchdraw an image:
- rectangular blocky stretchdraw, like this image (png)
- square blocky stretchdraw, like this image (png)
- 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
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
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
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.
