Rasterize QML SVG Image in Alpha8 format

落爺英雄遲暮 提交于 2019-12-13 07:27:12

问题


Importing a set of 80 icons in QML as non-visible images to be used for shader sources (for arbitrary colorization):

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

I discover that my memory consumption has skyrocketed, from 45 mb to 128 mb, a whooping ~185% increase, thats 83 extra mb for the 80 icons.

It was expected, after all, 512 * 512 * 4 / 1024 / 1024 makes up for exactly 1 mb of memory. However, that cost is not acceptable, especially in the face of targeting mobile phones with the app.

I could reduce the rasterization size, however, I want the icons to be nice and crisp. The icon size itself varies according to the device display, but for optimal user experience it needs to be about an inch or so. Given that most new high end phones are already pushing above 500 dpi, I'd really hate to scale the icons down and have them appear blurry.

Since the SVGs are supposed to be colorized in arbitrary colors, they are in effect simply alpha masks, meaning that all I really need is one of those 4 channels. Unfortunately, QML's Image doesn't seem to offer any sort of control, the SVG is rasterized to a RGBA image.

And indeed, if I

  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);
  }

I get the expected modest 20 mb increase in memory usage.

Any ideas how to save on some memory?


回答1:


2 hours later - good news, first and foremost, a custom QQuickImageProvider works out of the box with QImage::Format_Alpha8, no problems there. Unnecessary channels are eliminated.

But more importantly, I realized that the icons lend themselves very well to distance fields representation. So I now employ 128x128 SDF textures, which scale beautifully to far above 512x512, reducing the memory usage for the icons to the measly 1.25 mb, for a total of 64x reduction of ram usage compared to the initial implementation.

The only downside is the 3-4 seconds (on a Note 3 phone) additional startup, because the distance fields are calculated on startup, but there are remedies for this as well, I might switch to pre-computed SDFs or offload if to shaders, which would be a little more complex, but should reduce the time at least 5-fold.



来源:https://stackoverflow.com/questions/40821020/rasterize-qml-svg-image-in-alpha8-format

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!