光栅化 Alpha8 格式的 QML SVG 图像

Posted

技术标签:

【中文标题】光栅化 Alpha8 格式的 QML SVG 图像【英文标题】:Rasterize QML SVG Image in Alpha8 format 【发布时间】:2016-11-26 17:25:41 【问题描述】:

在 QML 中导入一组 80 个图标作为不可见图像用于着色器源(用于任意着色):

  property Image action: Image  sourceSize.width: 512; sourceSize.height: 512; source: "icons/action.svg"; mipmap: true; antialiasing: true 
  // 79 more of those

我发现我的内存消耗猛增,从 45 mb 增加到 128 mb,增加了约 185%,这 80 个图标增加了 83 mb。

这是意料之中的,毕竟512 * 512 * 4 / 1024 / 1024 正好占了 1 mb 的内存。但是,这样的成本是不可接受的,尤其是在使用该应用程序定位手机的情况下。

我可以减小光栅化大小,但是,我希望图标美观且清晰。图标大小本身因设备显示而异,但为了获得最佳用户体验,它需要大约一英寸左右。鉴于大多数新的高端手机已经超过 500 dpi,我真的不想缩小图标并让它们显得模糊。

由于 SVG 应该以任意颜色着色,因此它们实际上只是 alpha 蒙版,这意味着我真正需要的只是这 4 个通道之一。不幸的是,QML 的Image 似乎没有提供任何类型的控制,SVG 被光栅化为 RGBA 图像。

确实,如果我

  QVector<QImage> imgs;
  imgs.reserve(80);
  QDirIterator it(":/icons", QDirIterator::Subdirectories);
  while (it.hasNext()) 
      QSvgRenderer renderer (it.next());
      QImage ic(512, 512, QImage::Format_Alpha8);
      ic.fill(Qt::transparent);
      QPainter pp(&ic);
      renderer.render(&pp);
      imgs.append(ic);
  

我的内存使用量预计会适度增加 20 mb。

任何想法如何节省一些内存?

【问题讨论】:

如果您不需要更改显示尺寸,您可以在 C++ 中执行此操作并缓存生成的图像/位图。根据平台,这甚至可能在安装时实现 qml ShaderEffect 需要图像,我还没有测试过它是否可以直接与QImage 一起使用,但如果它确实考虑到 qml 的设计决策和缺乏内置 qml 的 ImageQImage 之间的互操作性。 有趣,我会假设它可以工作,因为QImage 是像素数据图像的主要 C++ 类型,并且 QQuick Image 元素也使用它。 @KevinKrammer - QImage 在 qtquick1 中使用 QML,但在 qtquick2 中已删除,现在您需要推出自己的图像提供程序来获得互操作性。 我不确定 QtQuick1 有 ShaderEffect,我认为这是 QtQuick2 中的新功能。还是您的意思是Image 元素?它在内部使用QImage IO 基础架构,是的,您可以使用图像提供程序来提供通过自定义 URL 在其他地方加载的图像。在缓存图像的情况下没有必要,因为当然可以简单地使用每个图像的文件 URI。 【参考方案1】:

2 小时后 - 好消息,首先,自定义 QQuickImageProviderQImage::Format_Alpha8 开箱即用,没有问题。消除不必要的渠道。

但更重要的是,我意识到这些图标非常适合表示距离场。所以我现在使用 128x128 SDF 纹理,它可以很好地缩放到远高于 512x512,将图标的内存使用量减少到区区 1.25 mb,与初始实现相比,内存使用量总共减少了 64 倍。

唯一的缺点是 3-4 秒(在 Note 3 手机上)额外启动,因为距离场是在启动时计算的,但也有补救措施,我可能会切换到预先计算的 SDF 或卸载如果到着色器,这会稍微复杂一些,但应该将时间减少至少 5 倍。

【讨论】:

以上是关于光栅化 Alpha8 格式的 QML SVG 图像的主要内容,如果未能解决你的问题,请参考以下文章

QGis:如何将svg或光栅图像导入Quantum GIS?

我可以阻止静止的 SVG 图像在 QML 中使用过多的 CPU 资源吗?

光栅化:一种实际的实现

iPhone Safari 中的 PNG 图像呈现光栅化问题

带有富文本的 QML 文本元素:如何调整 <img> 的垂直位置

QML中的SVG未在Android上显示