decodeToImage static method

Future<ImageProvider<Object>> decodeToImage(
  1. String blurHash,
  2. int width,
  3. int height, {
  4. double punch = 1.0,
})

Implementation

static Future<ImageProvider> decodeToImage(
    String blurHash, int width, int height,
    {double punch = 1.0}) async {
  if (blurHash.length < 6) throw Exception("BlurHash too short");

  final sizeFlag = _decode83(blurHash[0]);
  final numY = (sizeFlag / 9).floor() + 1;
  final numX = (sizeFlag % 9) + 1;

  final quantMaxValue = _decode83(blurHash[1]);
  final maxValue = (quantMaxValue + 1) / 166.0;

  final colors = <List<double>>[];

  int index = 2;
  final dcValue = _decode83(blurHash.substring(index, index + 4));
  index += 4;
  colors.add(_decodeDC(dcValue));

  for (int i = 1; i < numX * numY; i++) {
    final acValue = _decode83(blurHash.substring(index, index + 2));
    index += 2;
    colors.add(_decodeAC(acValue, maxValue * punch));
  }

  final pixels = Uint8List(width * height * 4);
  int byteIndex = 0;

  for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      double r = 0, g = 0, b = 0;

      for (int j = 0; j < numY; j++) {
        for (int i = 0; i < numX; i++) {
          final basis = cos(pi * x * i / width) * cos(pi * y * j / height);
          final color = colors[i + j * numX];
          r += color[0] * basis;
          g += color[1] * basis;
          b += color[2] * basis;
        }
      }

      final ir = _linearToSRGB(r);
      final ig = _linearToSRGB(g);
      final ib = _linearToSRGB(b);

      pixels[byteIndex++] = ir;
      pixels[byteIndex++] = ig;
      pixels[byteIndex++] = ib;
      pixels[byteIndex++] = 255;
    }
  }

  final completer = Completer<ui.Image>();
  ui.decodeImageFromPixels(
    pixels,
    width,
    height,
    ui.PixelFormat.rgba8888,
    (img) => completer.complete(img),
  );

  final ui.Image img = await completer.future;
  final byteData = await img.toByteData(format: ui.ImageByteFormat.png);
  return MemoryImage(byteData!.buffer.asUint8List());
}