iconDataToImageBytes function

Future<Uint8List?> iconDataToImageBytes(
  1. IconData iconData, {
  2. double size = 25.0,
  3. Color color = CupertinoColors.black,
})

Renders an IconData to PNG bytes for use in native platform views.

The size parameter is the logical font size of the glyph. The output is always a square size × size logical-pixel bitmap with the glyph's visible bounds centered inside it. This keeps the embedded icon's effective dimensions consistent regardless of how much line-box leading the source font reports — so native containers like UITabBar lay out a predictable distance between icon and label.

Results are memoised per (glyph, font, size, colour, device pixel ratio); see clearIconImageCache.

Implementation

Future<Uint8List?> iconDataToImageBytes(
  IconData iconData, {
  double size = 25.0,
  Color color = CupertinoColors.black,
}) {
  final double pixelRatio =
      ui.PlatformDispatcher.instance.views.first.devicePixelRatio;
  final String key =
      '${iconData.codePoint}|${iconData.fontFamily}|${iconData.fontPackage}'
      '|${size.toStringAsFixed(3)}|${pixelRatio.toStringAsFixed(3)}'
      '|${color.toARGB32()}';

  final Future<Uint8List?>? cached = _iconBytesCache[key];
  if (cached != null) return cached;

  if (_iconBytesCache.length >= _kIconBytesCacheLimit) {
    _iconBytesCache.remove(_iconBytesCache.keys.first);
  }

  final Future<Uint8List?> pending = _renderIconToImageBytes(
    iconData,
    size: size,
    color: color,
    pixelRatio: pixelRatio,
  );
  _iconBytesCache[key] = pending;
  // A null result means the glyph could not be rasterised. Don't hold onto
  // that — the next caller should be free to try again.
  pending
      .then((Uint8List? bytes) {
        if (bytes == null) _iconBytesCache.remove(key);
      })
      .catchError((Object _) {
        _iconBytesCache.remove(key);
      });
  return pending;
}