如何在 Qt/hook QPainter 中渲染没有抗锯齿的 SVG 以避免抗锯齿?
How to render an SVG without antialiasing in Qt/hook QPainter to avoid antialiasing?
我需要渲染一个仅矢量的SVG,而不在Qt中抗锯齿;具体来说,我不希望生成的图像包含任何与源文件中指定的颜色不完全一样的颜色。
在QImage
中加载SVG时,Qt默认使用抗锯齿;即使使用显式QSvgRenderer::render
,QPainter::Antialiasing
渲染提示也会被忽略。
事实证明这是显而易见的,因为QSVGTinyDocument::draw
似乎是实际开始绘图的人,正在强制设置它:
//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
在paintEngine()
虚拟方法中返回包装器QPaintEngine
),但我找不到任何干净的方法来拦截和更改渲染提示在通往实际QPaintEngine
的路上。
QPaintEngine::update()
方法似乎是QPaintEngine
接收标志的方式,接收对QPaintEngineState
的引用,这是一个可怕的笨蛋,只提供getter,而getter又反过来
- 不是
virtual
,因此您无法提供实现; - 在内部只是假设它实际上是通过粗暴地投射
this
指针并访问其字段来操作内部子类(QPainterState
)的实例。
此外,即使只是提供一个刚刚转发的QPaintEngine
也会导致QPainter
代码内部出现段错误,所以我很快就停止了。
长话短说:
- 有没有办法强制禁用/拦截和忽略/...
QPainter::Antialiasing
在QPainter
上呈现提示?(QT_NO_ANTIALIASING
环境变量不计算在内,因为它仅在没有QT_NO_DEBUG
的构建中启用); - 更一般地说,如何在不抗杀的情况下将 SVG 渲染到
QImage
?
我能想到的唯一解决方案是实现自己的SVG渲染器。使用nanosvg
这是微不足道的,但很少有人决定这样做。此外,像几乎所有其他解析器一样,nanosvg
不支持每个 SVG 功能(如过滤器等)。无论如何,这里有一个例子。无论您是否要(抗)锯齿,您都将拥有完全控制权。
不是最佳解决方案,但可能会对您有所帮助,方法是使用蒙版删除临时图像中的 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 中找到。
- Qt VTK交互风格的信号到小部件
- QT在错误的班级中寻找空位
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 如何在Qt窗口小部件中使用QStringView(或QStringRef)
- 如何在Qt C++中更改光标
- 如何在MS Visual Studio 2019中运行QT UI
- QT通过C++添加映射QML项目
- libssh 的函数在构建 libssh 时无法在 Qt 和 cmake 错误中找到
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 使用Qt C++计算类似Git的SHA1哈希
- Qt focusObjectChanged example?
- 如何在cpp文件之间切换窗口?在Qt中
- Qt在"debug"模式下正确渲染此SVG,但在"release"
- 如何在 Qt/hook QPainter 中渲染没有抗锯齿的 SVG 以避免抗锯齿?
- 如何使用 QT c++ 打开 SVG
- 有没有办法使用任何Qt库类从SVG数据中获取正确的边界矩形
- QT中的自定义外观svg GUI小部件,性能非常差
- 在qt中改变svg的颜色
- Qt QIcon SVG不同尺寸