import 'dart:typed_data'; import 'dart:ui'; import 'package:flutter/cupertino.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:jdenticon_dart/jdenticon_dart.dart'; import 'package:random_string/random_string.dart'; /// Identicon utilities /// /// @author Pierre Hubert // Based on https://stackoverflow.com/a/63215502/3781411 Future svgToPng(BuildContext context, String svgString, {int? svgWidth, int? svgHeight}) async { DrawableRoot svgDrawableRoot = await svg.fromSvgString(svgString, "svg"); // to have a nice rendering it is important to have the exact original height and width, // the easier way to retrieve it is directly from the svg string // but be careful, this is an ugly fix for a flutter_svg problem that works // with my images String temp = svgString.substring(svgString.indexOf('height="') + 8); int originalHeight = svgHeight ?? int.parse(temp.substring(0, temp.indexOf('p'))); temp = svgString.substring(svgString.indexOf('width="') + 7); int originalWidth = svgWidth ?? int.parse(temp.substring(0, temp.indexOf('p'))); // toPicture() and toImage() don't seem to be pixel ratio aware, so we calculate the actual sizes here double devicePixelRatio = MediaQuery.of(context).devicePixelRatio; double width = originalHeight * devicePixelRatio; // where 32 is your SVG's original width double height = originalWidth * devicePixelRatio; // same thing // Convert to ui.Picture final picture = svgDrawableRoot.toPicture(size: Size(width, height)); // Convert to ui.Image. toImage() takes width and height as parameters // you need to find the best size to suit your needs and take into account the screen DPI final image = await picture.toImage(width.toInt(), height.toInt()); ByteData bytes = (await image.toByteData(format: ImageByteFormat.png))!; return bytes.buffer.asUint8List(); } Future genIdenticon(BuildContext context, {int size: 100}) async { final identicon = Jdenticon.toSvg(randomString(25), size: size); return svgToPng(context, identicon, svgHeight: size, svgWidth: size); }