PDA

View Full Version : Creating an Icon-Editor



Nedec
23rd January 2010, 11:30
Hello,

I'm currently reading the "C++ GUI Programming with Qt 4"-book.

In chapter 5, you create a custom "icon editor", which enables you to edit each pixel of an icon. The icon is stored in a QImage (Format_ARGB32).

When there is a mousePressEvent, a pixel is painted.


void IconEditor::mousePressEvent(QMouseEvent *event)
{
if(event->buttons() & Qt::LeftButton) {
setImagePixel(event->pos(), true);
} else if(event->buttons() & Qt::RightButton) {
setImagePixel(event->pos(), false);
}
}


void IconEditor::setImagePixel(const QPoint &pos, bool opaque)
{
int i = pos.x() / zoom;
int j = pos.y() / zoom;


if(image.rect().contains(i, j)) {
QRgb pixelColor = image.pixel(i, j);
if(opaque) {
image.setPixel(i, j, penColor().rgba());
} else {
image.setPixel(i, j, qRgba(0, 0, 0, 0));
}

update(pixelRect(i, j));
}
}



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

for(int i = 0; i < image.width(); ++i) {
for(int j = 0; j < image.height(); ++j) {
QRect rect = pixelRect(i, j);
if(!event->region().intersect(rect).isEmpty()) {
QColor color = QColor::fromRgba(image.pixel(i, j));
if(color.alpha() < 255)
painter.fillRect(rect, color);
painter.fillRect(rect, color);
}
}
}
}

It works, but unfortunately very slow. Especially when the images are quite large. Then it takes some seconds to draw a pixel and it is inpossible to draw a continuous line. How is this solved in "real" image processing applications?


And sorry for my bad english. :)

wysota
23rd January 2010, 14:55
This paintEvent() implementation is very inefficient.

Nedec
29th January 2010, 12:19
Hi,

I know, that paintEvent() repainted the whole area, even if just one pixel changed.

Now, paintEvent() looks like this:

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

QRect updateRect = event->rect();
updateRect = QRect(updateRect.topLeft() / zoom, updateRect.size() / zoom);

for(int i = updateRect.left(); i <= updateRect.right(); ++i) {
if(!image.rect().contains(i, 0)) break;
for(int j = updateRect.top(); j <= updateRect.bottom(); ++j) {
if(!image.rect().contains(0, j)) break;
QRect rect = pixelRect(i, j);
if(!event->region().intersect(rect).isEmpty()) {
QColor color = QColor::fromRgba(image.pixel(i, j));
if(color.alpha() < 255)
painter.fillRect(rect, color);
painter.fillRect(rect, color);
}
}
}
}


So, only the part that changed is repainted. But it's still not possible to paint a continuous line.

Is there a better way to implement paintEvent()?

faldzip
29th January 2010, 12:58
Since mouse events are not coming on every one pixel change when moving cursor fast, then you have draw line (not only pixel) from the last mouse position (which you have to save on mouse move event I think) to current position.

Nedec
29th January 2010, 13:06
That sounds simple. I will try it, thank you. :)

arunpk
22nd March 2012, 06:58
I have this icon editor in my project..........i need to know how can i display the text on this icon editor....
For Ex: I have a line edit in which am goingto eb=nter a text which it should display on the icon editor.......... how can i do this???pls help