c++ - 如何在 Qt/hook QPainter 中渲染没有抗锯齿的 SVG 以避免抗锯齿?
问题描述
我需要在 Qt中渲染一个没有抗锯齿的纯矢量 SVG;具体来说,我不希望生成的图像包含与源文件中指定的颜色不完全相同的任何颜色。
在 a 中加载 SVG 时QImage
,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
返回虚拟方法QPaintEngine
中的包装paintEngine()
),但我找不到任何干净的方法来拦截和更改渲染提示到实际QPaintEngine
.
该QPaintEngine::update()
方法似乎是 aQPaintEngine
接收标志的方式,接收对 a 的引用QPaintEngineState
,这是一个可怕的 kludge,只提供 getter,而这反过来
- 不是
virtual
,所以你不能提供你的实现; - 内部只是假设它实际上是通过粗暴地转换指针并访问其字段来操作内部子类 (
QPainterState
)的一个实例。this
此外,即使只是提供一个just-forwarding也会QPaintEngine
导致QPainter
代码内部出现段错误,所以我很快就停止了。
长话短说:
- 有没有办法强制禁用/拦截和忽略/...上的
QPainter::Antialiasing
渲染提示QPainter
?(QT_NO_ANTIALIASING
环境变量不计算在内,因为它仅在没有 的构建中启用QT_NO_DEBUG
); - 更一般地说,如何在
QImage
不进行抗锯齿的情况下将 SVG 渲染为 a?
解决方案
The only solution I can think of is to implement your own SVG renderer. This is trivial using nanosvg
, yet few people decide to do this. Also, like almost every other parser out there, nanosvg
does not support every SVG feature (like filters, ...). Anyway, here's an example. You will have complete control, whether you want (anti)aliasing or not.
推荐阅读
- python - Python: {"errors":{"":["无法将当前 JSON 数组(如 [1,2,3])反序列化为类型 '
- sml - 在标准 ML 中声明相互依赖的值和函数
- firebase - Google Firebase 收到一封新用户注册的电子邮件
- spring-boot - 使用邮递员返回错误请求,但未在单元测试 Spring Boot 中返回
- php - 如何使用php从路径中获取最后一个和倒数第二个文件夹名称?
- python-3.7 - 如何从 Python3 中的输出创建一个数组
- regex - 在 PHP 7.4.* 中使用 preg_replace 保留空格、拉丁文和西里尔字符的正确方法是什么?
- javascript - Styled-components React HTML 元素工厂
- c# - 我无法使用机器人在不和谐频道上显示图像
- python - Pandas 不连续的真值行来查找每个段的 min()