PDA

View Full Version : Draw rectangle on QImage



^NyAw^
24th January 2013, 19:19
Hi,

I'm trying to draw a rectangle into a QImage using QPainter but I don't know what I'm doing wrong. This code is executed out of the paintEvent



QPainter qPainter(&qImage);
qPainter.setBrush(Qt::NoBrush);
qPainter.setPen(Qt::red);
qPainter.drawRect(iX,iY,iWidth,iHeight);
ui.imageLabel->setPixmap(QPixmap::fromImage(qImage));


The image is showed but not the rectangle.
"iX,iY,iWidth,iHeight" have values into the image size.

Thanks,

Viper666
24th January 2013, 19:21
because you must at first set image and after that draw rectangle because you overflow your retangle with image

^NyAw^
24th January 2013, 20:29
Hi,

The image is readed before painting the rectangle

wysota
24th January 2013, 21:02
Try calling qPainter.end() before converting the image to a pixmap.

^NyAw^
25th January 2013, 09:49
Hi,



Try calling qPainter.end() before converting the image to a pixmap.


Same result. I've also tryied to save the image on disk after calling "qPainter.end()" but the image is the same as the input image.

Maybe there is a better way to do what I want:
I have an image loaded from a Database(the image is loaded correctly). The Database also returns me a position and dimension of a rectangle that I want to show over the image. The image is painted on a QLabel scaling it to fill the QLabel dimension(mantaining the aspect ratio of the image), so the position to paint the rectangle are different. This is why I want to paint the rectangle directly into the image before scaling the image.

Thanks,

wysota
25th January 2013, 11:27
Please provide some minmal compilable example reproducing the problem.

^NyAw^
25th January 2013, 11:35
Hi,

I've tried this code in the constructor of a simple program.


QImage qImage("a.bmp");
QPainter qPainter(&qImage);
qPainter.setBrush(Qt::NoBrush);
qPainter.setPen(Qt::red);
qPainter.drawRect(150,150,50,50);
bool bEnd = qPainter.end();
qImage.save("b.bmp");


With this I'll get the image "b.bmp" that is the same as "a.bmp" but with a red rectangle painted on position (150px,150px) with a widht and height of 50px.
This don't work as "b.bmp" is identical as "a.bmp"

Thanks,

wysota
25th January 2013, 11:42
What is the format of the BMP image? Is it 8b (indexed) or 24b (true color)?

^NyAw^
25th January 2013, 11:59
Hi,

It is 8 byte indexed image

Added after 5 minutes:

Hi,

Thanks Wysota. This is the problem. I've transformed the image to a 32 bit RGB and now it works.
I had not thought that the image was indexed.

wysota
25th January 2013, 12:03
Ok, that explains everything :) In that case you need to use colours from the colour table assigned to the image. Whenever you want to pass a colour, you pass the index from the colour table (0-255) instead of the real colour. Since "red" translates to QColor("red") which in turn translates to QRgb = #00FF0000 = 16711680, the value you are passing is out of scope of the colour table and thus you get a transparent colour.

The easiest solution I can think of is to use QPixmap instead of QImage. Other than that, you can either do a lookup in the colour table (QImage::color()) to find "red" there (if it exists) or convert the indexed image to true color.

^NyAw^
25th January 2013, 12:37
Hi,

Converting the image to a 32 bit RGB is working. For the moment I don't need speed up my application but I will cosider to use QPixmap instead of QImage.

Thanks,

wysota
25th January 2013, 12:48
QPixmap will also convert your image to (most probably) 24 bit.

^NyAw^
25th January 2013, 13:33
Hi,

Finally I decided to change the way of displaying the rectangle on the image.
Now I'm using the "paintEvent":


void imageLabel::paintEvent(QPaintEvent *event)
{
QLabel::paintEvent(event);
if (!m_qImage.isNull())
{
QImage qImageScaled = m_qImage.scaled(QSize(width(),height()),Qt::KeepAs pectRatio,Qt::FastTransformation);
double dAspectRatio = (double)qImageScaled.width()/(double)m_qImage.width();
int iX = m_iX*dAspectRatio;
int iY = m_iY*dAspectRatio;
int iWidth = m_iWidth*dAspectRatio;
int iHeight = m_iHeight*dAspectRatio;

QPainter qPainter(this);
qPainter.drawImage(0,0,qImageScaled);
qPainter.setBrush(Qt::NoBrush);
qPainter.setPen(Qt::red);
qPainter.drawRect(iX,iY,iWidth,iHeight);
}
}


Using the aspect ratio I can calculate the new position and dimension of the rectangle.
I use this way because painting on the image can get a rectangle that is not visible depending on the widht of the pen and the new size of the image. In this way the rectangle always is 1px width and displayed well.

Thanks anyway,