以Alpha8格式栅格化QML SVG图像

时间:2016-11-26 17:25:41

标签: image qt memory svg qml

将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。

任何想法如何节省一些记忆?

1 个答案:

答案 0 :(得分:1)

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

但更重要的是,我意识到这些图标非常适合距离场表示。因此,我现在采用128x128 SDF纹理,可以精确地扩展到512x512以上,将图标的内存使用量减少到1.25 mb,与初始实现相比,ram使用量减少了64倍。

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