C++ 如何在Qt/hook QPainter中不使用抗锯齿渲染SVG以避免抗锯齿?
我需要在Qt中渲染一个仅矢量的SVG而不进行抗锯齿;具体来说,我不希望生成的图像包含任何与源文件中指定的颜色不完全相同的颜色 在C++ 如何在Qt/hook QPainter中不使用抗锯齿渲染SVG以避免抗锯齿?,c++,qt,svg,antialiasing,C++,Qt,Svg,Antialiasing,我需要在Qt中渲染一个仅矢量的SVG而不进行抗锯齿;具体来说,我不希望生成的图像包含任何与源文件中指定的颜色不完全相同的颜色 在QImage中加载SVG时,默认情况下,Qt使用抗锯齿;即使显式使用qsvgrender::render,也会忽略QPainter::Antialiasingrender提示 这一点很明显,因为似乎是真正开始绘图的人,QSVGTinyDocument::draw: 为了避免这种情况,我尝试创建一个自定义的QPaintEngine包装默认的QImage以返回paintEn
QImage
中加载SVG时,默认情况下,Qt使用抗锯齿;即使显式使用qsvgrender::render
,也会忽略QPainter::Antialiasing
render提示
这一点很明显,因为似乎是真正开始绘图的人,QSVGTinyDocument::draw
:
为了避免这种情况,我尝试创建一个自定义的QPaintEngine
包装默认的QImage
以返回paintEngine()
虚拟方法中的包装QPaintEngine
),但是,我找不到任何干净的方法来截取和更改实际QPaintEngine
过程中的渲染提示
QPaintEngine::update()
方法似乎是QPaintEngine
接收标志的方式,它接收对QPaintEngineState
的引用,这是一个可怕的乱码,只提供getter,而getter反过来
- 不是虚拟的,因此无法提供实现李>
- 在内部,只需假设它实际操作内部子类(
)的实例并访问其字段QPainterState
QPaintEngine
也会导致QPainter
代码内部出现SEGFULTS,因此我很快就停止了
长话短说:
- 有没有办法强制禁用/拦截并忽略/。。。
在QPainter::抗锯齿
上呈现提示?(不计算,因为它仅在没有QPainter
的版本中启用)李>QT\u NO\u DEBUG
- 更一般地说,如何在不进行反序列化的情况下将SVG渲染为
QImage
QImage
s,那么它应该可以完成这项工作
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中找到。我能想到的唯一解决方案是实现自己的SVG渲染器。使用
nanosvg
,这是微不足道的,但很少有人决定这么做。此外,与几乎所有其他解析器一样,nanosvg
不支持所有SVG特性(如过滤器,…)。无论如何,这里有一个,如果您愿意,可以移植到Qt
。无论您是否想要(消除)混叠,您都可以完全控制。消除混叠不仅限于外部边界,甚至可以应用于内部填充不同的区域之间的边界,通过混合它们来“发明”新颜色。这段代码将在外部边框上显示一个别名,但不会显示一个真正的别名图像,该图像仅由SVG文件中明确指定的颜色组成。
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;
}