C ++ and Qt: drawing program - visualization of transparent lines without alpha-articular overlap

I started creating a drawing program that interacts with drawing tablets. Depending on the pen pressure on the tablet, I change the value of the alpha line of the line. This mechanism works.

The thin lines look decent and it looks like a real sketch. But since I draw lines between two points (for example, in the Qt doodle tutorial) to draw, there is an alpha overlap between the joints of the lines, and this is very noticeable for thick strokes.

This is the effect with the line conveyor:

As you can see, there is an ugly alpha mix between the line segments.

To solve this problem, I decided to use QPainterPath strings for rendering. Two problems with this:

  • A long, continuous, thick path quickly lags behind the program.
  • Since the path is connected, it acts as one, so any change in the alpha value affects the entire path (which I do not need, since I want to keep the blending effect).

The following images use QPainterPath .

The blend effect I want to keep.

The following figure shows a second problem that changes the alpha and thickness of the entire path enter image description here

The red text should read: "if more pressure is added without removing the pen from the surface of the tablet, the line thickens" (and alpha becomes opaque)

Another thing is that with this approach I can only get a mixed trace from dark to light (or a thick thin path width), but not from light to dark. I’m not sure why this effect occurs, but I believe that it relates to path line segments that are being updated as a whole.

I did a program to increase / decrease the alpha and line thickness depending on the pen pressure on the tablet.

The problem is that I want to render lines without alpha overlap, and QPainterPath updates the entire alpha path and thickness that I don't want.

This is the code that creates the path:

  switch(event->type()){ case QEvent::TabletPress: if(!onTablet){ onTablet = true; //empty for new segment freePainterPath(); path = new QPainterPath(event->pos()); } break; case QEvent::TabletRelease: if(onTablet) onTablet = false; break; case QEvent::TabletMove: if(path != NULL) path->lineTo(event->pos()); if(onTablet){ //checks for pressure of pen on tablet to change alpha/line thickness brushEffect(event); QPainter painter(&pixmap); //renders the path paintPixmap(painter, event); } break; default:; } update(); 

The desired effect that I want as one path (image created using the Krita paint program): enter image description here

+4
source share
2 answers

To emulate a Krita drawing program:

  • Back up the original target surface.
  • Draw a brush on the surface of the scratches that starts completely transparent.
  • On this surface, your compost rule is “take maximum opacity.”
  • Watch the dirty areas of this surface and make a traditional composite (scratch surface) on (the original target surface) and show the result. Make sure that this operation does not damage the original surface of the target.

Now you do not need to save the entire original target surface - only the parts that you painted with this tool. (A good lazy tile-based image processing system will make this easier).

Depending on the size of the segment with which you draw, you can interpolate between the segments so that the brush strength is slightly less sharp. The shape of your brush may also require work. But they do not depend on the issue of transparency.

Regarding the oddities of Qt, I don't know enough Qt to tell you how to deal with the quirks of Qt brush code. But the above key-mask strategy should solve your alpha overlap problem.

I do not know how to do this in Qt. Looking at the Qt layout modes, I don’t see an obvious way to say “take maximum” as alpha alpha. Maybe something involving both color and alpha channels in some smart way.

+3
source

I know that this question is very old and has an accepted answer, but if someone needs an answer, here it is:

You need to set the composition mode for the artist. Now he draws both the source and destination.

 painter.setCompositionMode(QPainter::CompositionMode_Source); 

If you want your transparent areas to be displayed according to the basic drawings, you need to return the composition mode of your result to CompositionMode_SourceOver and draw as intended.

I do not know if you are still looking for an answer, but I hope this helps someone.

+5
source

Source: https://habr.com/ru/post/1493071/


All Articles