imageToFloat32Tensor static method

Future<Tensor> imageToFloat32Tensor(
  1. Image image, {
  2. int x = 0,
  3. int y = 0,
  4. int? width,
  5. int? height,
  6. MemoryFormat memoryFormat = MemoryFormat.contiguous,
})

Convert an Image to a Tensor

Implementation

static Future<Tensor> imageToFloat32Tensor(
  final ui.Image image, {
  int x = 0,
  int y = 0,
  int? width,
  int? height,
  final MemoryFormat memoryFormat = MemoryFormat.contiguous,
}) async {
  if (memoryFormat != MemoryFormat.contiguous &&
      memoryFormat != MemoryFormat.channelsLast) {
    throw ArgumentError('Unsupported memory format: $memoryFormat');
  }
  if (width == null || height == null) {
    width = image.width;
    height = image.height;
  }
  final bitmap = resizeImage(image, width, height);
  final int pixelsCount = height * width;
  const int channels = 3;

  // rgba
  const pixelFormat = ui.ImageByteFormat.rawExtendedRgba128;
  final pixels =
      (await bitmap.toByteData(format: pixelFormat))!.buffer.asFloat32List();

  // MemoryFormat
  //   - contiguous:
  //       - inputShape: 1*channels*height*width
  //       - [r0, r1, ..., g0, g1, ..., b0, b1, ...]
  //   - channelsLast:
  //       - inputShape: 1*channels*height*width
  //       - [r0, g0, b0, r1, g1, b1, ...]
  final Int64List inputShape;
  final double Function(int) generator;
  if (memoryFormat == MemoryFormat.contiguous) {
    inputShape = Int64List.fromList([1, channels, height, width]);
    generator = (index) {
      final pixelIdx = index % pixelsCount;
      final rgbIdx = index ~/ pixelsCount;
      return pixels[pixelIdx * 4 + rgbIdx];
      // final x = index % width!;
      // final y = (index ~/ width) % height!;
      // final channel = index ~/ (height * width);
      // return pixels[(y * width + x) * 4 + channel];
    };
  } else {
    inputShape = Int64List.fromList([1, height, width, channels]);
    generator = (index) {
      final pixelIdx = index ~/ channels;
      final rgbIdx = index % channels;
      return pixels[pixelIdx * 4 + rgbIdx];
      // final positionInHeightWidth = index ~/ channels;
      // final x = positionInHeightWidth ~/ height!;
      // final y = positionInHeightWidth % height;
      // final channel = index % channels;
      // return pixels[(y * width! + x) * 4 + channel];
    };
  }

  // rgb
  final imageMatrix =
      Float32List.fromList(List.generate(pixelsCount * channels, generator));

  // tensor
  return Tensor.fromBlobFloat32(imageMatrix, inputShape,
      memoryFormat: memoryFormat);
}