我已经开始创建一个与绘图板交互的绘图程序。根据笔在数位板上的压力,我更改了正在绘制的线条的 alpha 值。该机制有效。
细线看起来不错,看起来像一个真实的素描。但是因为我在两点之间画线(就像在 Qt 涂鸦教程中一样)来绘画,所以线接头之间有一个 alpha 重叠,并且对于粗笔画来说非常明显。
这是线对线连词的效果:
如您所见,线段之间存在难看的 alpha 混合。
为了解决这个问题,我决定使用QPainterPath 来渲染线条。
这有两个问题:
以下图像使用了 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 绘图程序创建的图像):
最佳答案
模拟 Krita 绘图程序:
现在,您不必保留整个原始目标表面 - 只需保留您使用此工具绘制的部分。 (一个好的基于图 block 的延迟写入成像系统将使这变得容易)。
根据您正在绘制的线段大小,您可能希望在线段之间进行插值,使画笔的强度稍微不那么尖锐。刷子的形状也可能需要改进。但这些与透明度问题无关。
至于Qt的怪癖,我对Qt的了解还不够,无法告诉大家如何处理Qt的刷机代码怪癖。但是上面的“key-mask”策略应该可以解决你的 alpha 重叠问题。
我不知道如何在 Qt 中执行此操作。扫视Qt compositing modes我没有看到一种明显的方式来表示“取最大值”作为生成的 alpha。也许以某种巧妙的方式同时涉及颜色和 alpha channel 。
关于C++ 和 Qt : Paint Program - Rendering Transparent Lines Without Alpha Joint Overlap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17822639/