Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;和Qt:Paint程序-渲染透明线,无Alpha关节重叠_C++_Qt - Fatal编程技术网

C++ C++;和Qt:Paint程序-渲染透明线,无Alpha关节重叠

C++ C++;和Qt:Paint程序-渲染透明线,无Alpha关节重叠,c++,qt,C++,Qt,我已经开始创建一个与绘图板交互的绘图程序。根据笔在平板电脑上的压力,我会更改正在绘制的线条的alpha值。这一机制有效 细线看起来不错,而且看起来是一幅真实的素描。但是因为我在两点之间画线(就像在Qt scribble教程中)来画画,所以线关节之间有一个alpha重叠,这对于粗笔划非常明显 这是线对线合并的效果: 如您所见,线段之间存在一个丑陋的alpha混合 为了解决这个问题,我决定使用QPainterPath来渲染线条。 这有两个问题: 一条长的、连续的、厚的路径很快就会使程序落后 因为路

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

细线看起来不错,而且看起来是一幅真实的素描。但是因为我在两点之间画线(就像在Qt scribble教程中)来画画,所以线关节之间有一个alpha重叠,这对于粗笔划非常明显

这是线对线合并的效果:

如您所见,线段之间存在一个丑陋的alpha混合

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

  • 一条长的、连续的、厚的路径很快就会使程序落后
  • 因为路径是连接的,所以对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 paint程序创建的图像):

    要模拟Krita paint程序:

  • 保留原始目标曲面的备份
  • 用刷子在一个完全透明的划痕表面上绘画
  • 在这个表面上,你的堆肥规则是“最大不透明度”
  • 跟踪该曲面的脏区域,并在(原始目标曲面)上执行(刮伤曲面)的传统合成并显示结果。确保此操作不会损坏原始目标表面
  • 现在,您不必保留整个原始目标曲面,只需保留使用此工具绘制的部分即可。(一个好的基于平铺的延迟写入成像系统将使这变得容易)

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

    至于Qt的奇怪之处,我对Qt的了解还不足以告诉您如何处理Qt的刷代码的怪癖。但是上面的“关键掩码”策略应该可以解决阿尔法重叠问题


    我不知道如何在Qt中执行此操作。看了一眼,我没有看到一个明显的方式来说“takemaximum”作为结果alpha。可能以某种巧妙的方式涉及到颜色和alpha通道。

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

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

    painter.setCompositionMode(QPainter::CompositionMode_Source);
    
    如果希望透明区域通过基础图形显示,则需要将结果的合成模式设置回“合成模式”\u SourceOver and draw over destination


    我不知道你是否还在寻找答案,但我希望这能帮助到别人。

    那么,对于克里塔最后一次的扭动:你是不是打算让折回的画笔不会在画笔的上一个笔划上合成?如果画笔在同一区域来回移动,它不会变得更暗吗?这是一条单独的路径。我在平板电脑上使劲按,改变了字母。在克里塔语中,如果同一条路穿过它自己,它就会画过去。如果两条不同的路径相交,则可见透明交叉。但我并不真正关心这个细节。我只想画一些没有alpha重叠的线,就像第一幅图一样。