How to resize a network image before showing it as NetworkImage in flutter web?

Viewed 1094

My goal is to increase the performance of my website by downscaling images.

When i show NetworkImages they always render the full source image resolution (e.g. 7000x4667 pixel). The widget itself mostly has a smaller size (e.g. 200x200 pixel). I have the image url and want to scale the 7000x4667 pixel image down to 200x200 before loading it in the NetworkImage widget.

What i already tried is the answer from this question: Flutter - Resize network image That does work in flutter for mobil but not in flutter web as the line ByteData originalByteData = await originalUiImage.toByteData(); returns null in flutter web.

Already thank you a lot in advance for your help.

1 Answers

I found a solution that propably suits you . Speed is fantastic and size of the image is reduced significantly.

Flutter Print

late Uint8List targetlUinit8List;
late Uint8List originalUnit8List;

Future<Uint8List> _resizeImage() async {
  var imageUrl = Uri.parse('https://picsum.photos/250?image=9');
  http.Response response = await http.get(imageUrl);
  originalUnit8List = response.bodyBytes;

  ui.Image originalUiImage = await decodeImageFromList(originalUnit8List);
  ByteData? originalByteData = await originalUiImage.toByteData();
  print('original image ByteData size is ${originalByteData!.lengthInBytes}');

  var codec = await ui.instantiateImageCodec(originalUnit8List,
      targetHeight: 200, targetWidth: 200);
  var frameInfo = await codec.getNextFrame();
  ui.Image targetUiImage = frameInfo.image;

  ByteData? targetByteData =
      await targetUiImage.toByteData(format: ui.ImageByteFormat.png);
  print('target image ByteData size is ${targetByteData!.lengthInBytes}');
  targetlUinit8List = targetByteData.buffer.asUint8List();

  //remove delay function
  await Future.delayed(Duration(seconds: 2));
  return targetlUinit8List;
}

Then I have a futureBuilder for my example , but you can use anything you want :

if (snapshot.hasData) {
              children = <Widget>[
                const Icon(
                  Icons.check_circle_outline,
                  color: Colors.green,
                  size: 60,
                ),
                Padding(
                  padding: const EdgeInsets.only(top: 16),
                  child: Image.memory(snapshot.data!),
                )
              ];
            }

Working Example

Only thing left to implement is to dispose the unused variables , and I have no idea how to do it (I am not the best at flutter). I want to know if anyone implements this with disposed variables

Related