6

我已经开始创建一个与绘图板交互的绘图程序。根据笔在数位板上的压力,我会更改正在绘制的线条的 alpha 值。该机制有效。

细线看起来不错,看起来像一个真实的草图。但是由于我在两点之间画线(就像在 Qt scribble 教程中一样)来绘制,所以线关节之间存在 alpha 重叠,对于粗笔画来说非常明显。

这是线对线连接的效果:

如您所见,线段之间存在难看的 alpha 混合。

为了解决这个问题,我决定使用 aQPainterPath来渲染线条。这有两个问题:

  1. 一条长的、连续的、粗的路径很快就会滞后于程序。
  2. 由于路径是连接的,因此它充当一个路径,因此对 alpha 值的任何更改都会影响整个路径(我不希望这样做,因为我想保留混合效果)。

以下图像使用QPainterPath.

我想保留的混合效果。

下图显示了第二个问题,它改变了整个路径的 alpha 和粗细在此处输入图像描述

红色文本应为:“如果在不将笔从数位板表面移开的情况下施加更大的压力,则线条变粗”(并且 alpha 变得不透明)

另一件事是,通过这种方法,我只能得到从暗到亮(或从粗到细的路径宽度)的混合轨迹,但不能从亮到暗。我不确定为什么会出现这种效果,但我最好的猜测是它与整个路径更新的线段有关。

我确实让程序根据笔在平板电脑上的压力增加/减少 alpha 和线条粗细。

问题是我想渲染没有 alpha 重叠的线条并QPainterPath更新我不想要的整个路径的 alpha 和厚度。

这是创建路径的代码:

    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();

我想要作为单个路径的预期效果(使用 Krita 绘制程序创建的图像):在此处输入图像描述

4

2 回答 2

5

我知道这个问题很老,并且有一个公认的答案,但如果其他人需要答案,这里是:

您需要将painter的合成模式设置为source。它现在同时绘制源和目标。

painter.setCompositionMode(QPainter::CompositionMode_Source);

如果您希望透明区域通过底层绘图显示,则需要将结果的合成模式设置回 CompositionMode_SourceOver 并绘制目标。

我不知道你是否还在寻找答案,但我希望这对某人有所帮助。

于 2015-02-01T12:40:45.293 回答
4

要模拟 Krita 绘画程序:

  1. 保留原始目标表面的备份。
  2. 用刷子在开始时完全透明的划痕表面上绘画。
  3. 从表面上看,您的堆肥规则是“采取最大不透明度”。
  4. 跟踪该表面的脏区,并在(原始目标表面)上进行传统的(划痕表面)合成并显示结果。确保此操作不会损坏原始目标表面。

现在,您不必保留整个原始目标表面 - 只需保留您使用此工具绘制的部分即可。(一个好的基于 tile 的惰性写入成像系统将使这变得容易)。

根据您绘制的线段大小,您可能希望在线段之间进行插值,以使画笔的强度不那么锐利。你的刷子的形状也可能需要改进。但这些与透明度问题无关。

至于Qt的怪癖,我对Qt的了解还不够,无法告诉大家如何处理Qt刷码的怪癖。但是上面的“key-mask”策略应该可以解决你的 alpha 重叠问题。

我不知道如何在 Qt 中做到这一点。看一眼Qt 合成模式,我看不出有一种明显的方式可以说“取最大值”作为结果 alpha。也许以某种巧妙的方式涉及颜色和 Alpha 通道。

于 2013-07-24T01:29:42.457 回答