我需要在Qt中渲染不带锯齿的纯矢量SVG ;具体来说,我不希望结果图像包含的颜色与源文件中指定的颜色不完全相同。
在QImage
中加载SVG时,默认情况下Qt使用抗锯齿;即使显式使用QSvgRenderer::render
,QPainter::Antialiasing
呈现提示也会被忽略。
事实证明,QSVGTinyDocument::draw
是is forcing it set的实际来源,//sets default style on the painter
//### not the most optimal way
mapSourceToTarget(p, bounds);
QPen pen(Qt::NoBrush, 1, Qt::SolidLine, Qt::FlatCap, Qt::SvgMiterJoin);
pen.setMiterLimit(4);
p->setPen(pen);
p->setBrush(Qt::black);
p->setRenderHint(QPainter::Antialiasing);
p->setRenderHint(QPainter::SmoothPixmapTransform);
:
QPaintEngine
为避免这种情况,我尝试创建一个包装默认包装的自定义QImage
(然后甚至是QPaintEngine
的子类,以返回paintEngine()
虚拟方法中的包装QPaintEngine
) ,但是我找不到任何干净的方法来截取和更改渲染提示,直到到达实际的QPaintEngine::update()
。
QPaintEngine
方法似乎是QPaintEngineState
接收标志的方式,它接收到对virtual
的引用,这是一个仅提供吸气剂的可怕方法,反过来
QPainterState
,因此您无法提供实现; QPaintEngine
)by brutally casting the this
pointer的实例并访问其字段。此外,即使仅提供向前转发的QPainter
也会在QPainter::Antialiasing
代码的肠道内造成段错误,所以我很快就放弃了。
长话短说:
QPainter
上的QT_NO_DEBUG
渲染提示? (QT_NO_ANTIALIASING
environment variable不算在内,因为只有在没有QImage
的构建中才启用); inserted
?答案 0 :(得分:0)
不是最佳解决方案,但可能会对您有所帮助,方法是使用遮罩删除时间图像中的Alpha通道,从而创建别名渲染的外观。显示的函数将QImage
用作您当前呈现抗锯齿的对象,并返回一个等效的别名。
对于实时渲染,此解决方法可能是不切实际的,但是如果您只希望在预处理步骤中创建QImage
,则应该可以进行工作。
QImage convertToAliased(const QImage& source)
{
const auto mask = QPixmap::fromImage(source.createAlphaMask());
QImage image(source.size(), QImage::Format_ARGB32);
image.fill(Qt::transparent);
QPainter p;
p.begin(&image);
p.setClipRegion(QRegion(mask));
p.drawImage(QPoint(0, 0), source.convertToFormat(QImage::Format_RGB32));
p.end();
return image;
}
代码也可以在GitHub here中找到。
答案 1 :(得分:0)
我能想到的唯一解决方案是实现自己的SVG渲染器。使用nanosvg
这很简单,但很少有人决定这样做。同样,nanosvg
就像几乎其他所有解析器一样,不支持所有SVG功能(例如过滤器,...)。无论如何,这是一个example,您可以根据需要将其移植到Qt
。然后,无论是否要进行(抗)锯齿,您都将拥有完全的控制权。