PDA

View Full Version : 2 Questions about QPainter



SkripT
20th February 2006, 18:52
Hi all, I'm using Qt4.1 on WindowsXP. I've got 2 questions about QPainter class:
1) I want to know if it's possible and, in that case, how to paint in OR mode: painting under a surface that has been painted before. I need it because I've implemented a rubberband to select rectangular areas of an image. This is the process: first of all, I paint the image with drawImage function. After,as the rubberband changes its size or position, I want to delete the "old" rubberband painting the original portion of the image where it was the rubberband painted under the image. Finally I paint the "new" rubberband in the current position with drawRect. All this process is done in the paintEvent method of the widget that I use to paint under.
2) I have noticed that painting an image of 8 bits/pixel (a grayscsale image, for example) with drawImage function is much more slower that painting the same image with 32 bits/pixel (with equal r, g, and b channel for the case of grayscale images) :confused: Really strange. Anybody colud tell me what could be the cause? Maybe before drawing the image, qPainter forces the resolution, for some strange reason, to 32 bits/pixel if it's not the real resolution of the image? I don't know it's just a supposition...

Thanks.

wysota
20th February 2006, 20:47
Hi all, I'm using Qt4.1 on WindowsXP. I've got 2 questions about QPainter class:
1) I want to know if it's possible and, in that case, how to paint in OR mode: painting under a surface that has been painted before. I need it because I've implemented a rubberband to select rectangular areas of an image. This is the process: first of all, I paint the image with drawImage function. After,as the rubberband changes its size or position, I want to delete the "old" rubberband painting the original portion of the image where it was the rubberband painted under the image. Finally I paint the "new" rubberband in the current position with drawRect. All this process is done in the paintEvent method of the widget that I use to paint under.

You should be able to achieve it using QPainter::setCompositionMode.


2) I have noticed that painting an image of 8 bits/pixel (a grayscsale image, for example) with drawImage function is much more slower that painting the same image with 32 bits/pixel (with equal r, g, and b channel for the case of grayscale images) :confused: Really strange. Anybody colud tell me what could be the cause? Maybe before drawing the image, qPainter forces the resolution, for some strange reason, to 32 bits/pixel if it's not the real resolution of the image? I don't know it's just a supposition...

That's probably because the image has to be remapped to the painter's number of planes (32b) (and it has to be copied to do that) which is a lengthy process.

SkripT
21st February 2006, 11:03
Hi, relating to my question number 1, I've tried different Composition Modes but the result is always the same: the surface where I paint is always cleared, so only appears what I've painted on the last time :confused: Here's a simplified version of the code that I use:


void FotoEditorFotos::paintEvent(QPaintEvent *event)
{
QPainter painter;
painter.begin(this);

if (rectABorrar.isNull())
{
// Paint all the image for the first time centered on the widget
int rectW = arrodonirValor(imatge.width() * escala);
int rectH = arrodonirValor(imatge.height() * escala);
rectFoto.setRect((width() >> 1) - (rectW >> 1), (height() >> 1) - (rectH >> 1), rectW, rectH);

painter.drawImage(rectFoto, imatge);
}
else
{
// "rectSeleccio" defines the old position and size (geometry) of the rubberband and needs to be deleted with the original portion of the image, defined by "rectABorrar"
painter.setCompositionMode(QPainter::CompositionMo de_Destination);//I don't know if this is the Composition Mode that I should use????
painter.drawImage(rectSeleccio, imatge, rectABorrar);

rectABorrar.setRect(-1, -1, 0, 0);
}

// Code to Paint the rubberband.........

painter.end()
}

Anybody could tell me where's the mistake? Thanks.

wysota
21st February 2006, 11:49
Did you try QPainter::CompositionMode_Xor ?

BTW. Are you aware that the rubber band has its own implementation built into Qt?

SkripT
21st February 2006, 12:28
Did you try QPainter::CompositionMode_Xor ?

Yes but always clears the background, too. Very strange.


BTW. Are you aware that the rubber band has its own implementation built into Qt?

Yes I know that exists, but It's not useful for my case. I find it too simple.

SkripT
21st February 2006, 16:16
Anybody suggests me something that could explain why the background is cleared everytime that I try to delete the rubberband with the code above? I'm a little worried :(

wysota
21st February 2006, 20:57
Does the Qt example which demonstrates different composite modes work for you?

SkripT
22nd February 2006, 00:52
Does the Qt example which demonstrates different composite modes work for you?

Sorry wysota, could you tell me the name of this example, please?

Althought, maybe the problem that I have is that I paint in the paintEvent method and maybe, after calling to repaint, the background is cleared automaticly or something :confused:

wysota
22nd February 2006, 01:02
Sorry wysota, could you tell me the name of this example, please?

demos/composition.

SkripT
22nd February 2006, 10:31
wysota I've been looking the demo and I've noticed two main differences: they dont' use begin and end and they don't' paint in the paintEvent method (I think). I dont' know if these are the causes for my code not to work. But anyway I've seen that they repaint all the image everytime to delete the "old circle". And here's my question: do you think that painting all in a buffer(they use a qImage) and later paint this buffer on the destination widget (like a double buffering) is faster that paint every object to be drawn directly on the destination widget?? Thanks

wysota
22nd February 2006, 11:22
I think the reason may be that different platforms use different paint enigines and probably not all of them support composing. Probably that's why they used qImage, as it uses the raster engine which probably has composing capabilities built in. Otherwise the demo might not work on all systems. For example Windows uses the rastering engine by default too, while X11 uses PostScript and Mac uses QuickDraw. Additionaly some platform support may be needed for composite to work on different renderers (like the COMPOSITE extension to X11).

SkripT
22nd February 2006, 11:30
Ok thanks a lot

SkripT
22nd February 2006, 16:08
Hi again, relating with my first question, I think that's impossible to paint under a widget without clearing the background in the way that I want. I've tried different ways: setting transparent background, different composition modes, etc. but no success: everytime clears the background. The only solution is to paint again all the image everytime that the rubberband changes its position or size. But as you can see, this is very inefficient specially if the image has a big size. The problem is that the rubberband is painted with some delay since the mouse cursor and it's a bit annoying. I'm thinking in other solutions: does anybody knows a way to paint the image in background mode and in a specified fixed position and size like if it was permanently "painted" on the widget? So it releases of painting everytime the image. I think that a QLabel wouldn't be useful because it wouldn't be able to paint the rubberband under the label...