1

我正在使用 QT,并且能够创建一个基本的 MS 油漆铅笔绘图工具。我通过用线连接一系列点来创建铅笔工具。它对于不透明的细线看起来不错,但是对于粗线和透明线,我会得到一个 alpha 透明度重叠(因为这些线在一个共享点处相交)。我已经研究过,一些建议是绘制一个单独的透明缓冲区并在那里渲染并获得最大不透明度并将其渲染回原始缓冲区,但我真的不知道如何在 Qt 中做到这一点。

我对图形或 Qt 没有丰富的经验,所以我不知道这种方法。MyPaint 和 Krita 等程序如何处理画笔以保持漂亮的透明线条而不会重叠?

我不想要的:

在此处输入图像描述


我想要的效果: 在此处输入图像描述

4

2 回答 2

2

请参阅我对这个问题的回答。这里同样适用。

为了不提供链接,我将在这里重复答案:

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

Painter.setCompositionMode(QPainter::CompositionMode_Source);

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

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

于 2015-02-01T15:09:23.507 回答
2

由于您没有显示任何代码,我将假设您正在做的是存储一组点,然后在绘制函数中,使用画家绘制这些点。你得到的效果是当你在你已经绘制的区域上绘制时。

您可以用来防止这种情况的一种方法是使用 QPainterPath 对象。当鼠标按下事件发生时,使用 QPainterPath 对象的 moveTo 函数。然后为鼠标移动事件调用 lineTo 函数。

最后,在渲染方面,不是绘制点,而是渲染 QPainterPath 对象。

- - - - - 编辑 - - - - - - - - - - - - - - - - - - -

由于您添加了您想要的效果示例,我更了解您的问题,您可能无法在此处使用 QPainterPath,但我确实推荐它用于不透明的线条。

但是,如果您在将线条添加到 QPainterPath 之前计算出渐变变化,则可以使用带有 QPainterPath 的渐变笔并按照您想要的方式进行操作。或者...

您在原始答案中提到了这一点:-

在单独的透明缓冲区上绘制并在那里渲染并获得最大不透明度并将其渲染回原始缓冲区。

这听起来比单词缓冲区更复杂。实际上,您只需创建一个单独的 QImage 并绘制到它而不是屏幕上。然后在绘制屏幕时,您可以复制图像。要“获得最大不透明度”,您可以扫描图像上的位并查看 alpha 通道,或者保留一个单独的信息结构来记录笔的压力及其在每个点的位置。我希望获得 alpha 增加然后减少时的最大值和最小值,并线性插值渲染值,而不是尝试映射每分钟的变化。

将缓冲图像渲染回主图像时,我认为您需要在 QPainter 上设置一种合成模式,但在我的脑海中,我不确定是哪一种。阅读文档以了解他们的工作并与他们进行实验以了解他们产生的效果。

根据我在图形方面的经验,我经常发现您需要尝试一下,看看什么是有效的,并了解您正在做什么,尤其是当您发现您正在使用的方法开始变得缓慢并且您需要时优化它以合理的帧速率工作。

于 2013-07-24T07:45:59.960 回答