Rasterize QML SVG Image in Alpha8 format
在QML中导入80个图标集作为不可见图像以用于着色器源(用于任意着色):
1 2 | 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。
毕竟,
我可以减小栅格化的大小,但是,我希望图标既美观又清晰。图标大小本身根据设备显示的不同而有所不同,但是为了获得最佳的用户体验,图标大小大约需要1英寸左右。考虑到大多数新的高端手机已经将速度提高到500 dpi以上,我真的很讨厌缩小图标的大小并使它们显得模糊。
由于SVG应该以任意颜色进行着色,因此它们实际上只是alpha蒙版,这意味着我真正需要的只是这4个通道之一。不幸的是,QML的
确实,如果我
1 2 3 4 5 6 7 8 9 10 11 | 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内存使用量的适度增长。
有什么想法可以节省一些内存吗?
2小时后-好消息,首先,自定义
但更重要的是,我意识到这些图标非常适合用于距离场表示。 因此,我现在使用128x128 SDF纹理,可以很好地缩放到512x512以上,将图标的内存使用量减少到仅1.25 mb,与最初的实现相比,总共可以减少ram使用量64倍。
唯一的缺点是需要额外启动3-4秒(在Note 3手机上),因为距离字段是在启动时计算的,但是对此也有解决方法,我可能会切换到预先计算的SDF或卸载到着色器中 ,这会有些复杂,但应将时间减少至少5倍。