Flutter - convert and resize asset image to dart ui image

9,673

Solution 1

Been a while since was able to work on this side project, but was able to accomplish the conversion and resize using the image package:

import 'dart:ui' as ui;
import 'package:image/image.dart' as image;
import 'package:flutter/services.dart';

Future<ui.Image> getUiImage(String imageAssetPath, int height, int width) async {
  final ByteData assetImageByteData = await rootBundle.load(imageAssetPath);
  image.Image baseSizeImage = image.decodeImage(assetImageByteData.buffer.asUint8List());
  image.Image resizeImage = image.copyResize(baseSizeImage, height: height, width: width);
  ui.Codec codec = await ui.instantiateImageCodec(image.encodePng(resizeImage));
  ui.FrameInfo frameInfo = await codec.getNextFrame();
  return frameInfo.image;
}

Solution 2

You can achieve this without using the image package:

Future<ui.Image> getUiImage(String imageAssetPath, int height, int width) async {
  final ByteData assetImageByteData = await rootBundle.load(imageAssetPath);
  final codec = await ui.instantiateImageCodec(
    assetImageByteData.buffer.asUint8List(),
    targetHeight: height,
    targetWidth: width,
  );
  final image = (await codec.getNextFrame()).image;
}
Share:
9,673
JsonB
Author by

JsonB

Updated on December 17, 2022

Comments

  • JsonB
    JsonB over 1 year

    I'm attempting to take an asset image, resize the image to an arbitrary width and height, and convert the image to a dart ui image so that I can draw the image on a canvas using the drawImage method. This so I can adjust the image for different screen sizes.

    However I'm running into an issue resizing the image. I've attempted several different approaches but the best I've managed is to either draw the correct image data with the image cropped instead of resized, the data invalidated (incorrect decoding static) at the correct size, or the correct image data while failing to resize the image.

    My named imports are

    import 'dart:io' as io;
    import 'dart:ui' as ui;
    import 'package:flutter/widgets.dart' as widgets;
    import 'package:image/image.dart' as image;
    

    Some of my attempts are as follows:

    Displays the correct image data while failing to adjust the size:

    Future<ui.Image> loadUiImage(String imageAssetPath) async {
      widgets.Image widgetsImage = widgets.Image.asset(imageAssetPath, scale: 0.5);
      Completer<ui.Image> completer = Completer<ui.Image>();
      widgetsImage.image
        .resolve(widgets.ImageConfiguration(size: ui.Size(10, 10)))
        .addListener(widgets.ImageStreamListener((widgets.ImageInfo info, bool _){
          completer.complete(info.image);
        }));
      return completer.future;
    }
    

    Incorrectly crops the images without resizing, though the image data is correct:

    Future<ui.Image> loadUiImage(String imageAssetPath) async {
      final ByteData data = await rootBundle.load(imageAssetPath);
      List<int> bytes = data.buffer.asUint8List();
      image.Image iconImage = image.Image.fromBytes(100, 100, bytes);
      final Completer<ui.Image> completer = Completer();
      ui.decodeImageFromList(image.decodePng(image.encodePng(iconImage)).getBytes(), (ui.Image img) {
        return completer.complete(img);
      });
      return completer.future;
    }
    

    Invalidated image data, correctly resized image:

    Future<ui.Image> loadUiImage(String imageAssetPath) async {
      final ByteData data = await rootBundle.load(imageAssetPath);
      List<int> bytes = data.buffer.asUint8List();
      image.Image iconImage = image.Image.fromBytes(100, 100, bytes);
      final Completer<ui.Image> completer = Completer();
      ui.decodeImageFromList(image.encodePng(iconImage), (ui.Image img) {
        return completer.complete(img);
      });
      return completer.future;
    }
    

    I've also attempted to utilize the Bitmap method used here, but hit an error in the provided function

    Failed assertion: line 274 pos 12: 'bitmap.length == size': is not true

    in my attempted use after trying to resize the image.

    I'd greatly appreciate any help in solving this, thanks in advance.