halve function

RgbaImage halve(
  1. RgbaImage image, {
  2. required bool srgb,
})

image at half size (each side halved, at least 1), every pixel the average of up to four source pixels. Alpha is always averaged linearly.

Implementation

RgbaImage halve(RgbaImage image, {required bool srgb}) {
  final w = math.max(1, image.width >> 1);
  final h = math.max(1, image.height >> 1);
  final src = image.pixels;
  final out = Uint8List(w * h * 4);
  for (var y = 0; y < h; y++) {
    final y0 = math.min(y * 2, image.height - 1);
    final y1 = math.min(y * 2 + 1, image.height - 1);
    for (var x = 0; x < w; x++) {
      final x0 = math.min(x * 2, image.width - 1);
      final x1 = math.min(x * 2 + 1, image.width - 1);
      final a = (y0 * image.width + x0) * 4;
      final b = (y0 * image.width + x1) * 4;
      final c = (y1 * image.width + x0) * 4;
      final d = (y1 * image.width + x1) * 4;
      final o = (y * w + x) * 4;
      for (var ch = 0; ch < 3; ch++) {
        if (srgb) {
          final sum =
              _toLinear[src[a + ch]] +
              _toLinear[src[b + ch]] +
              _toLinear[src[c + ch]] +
              _toLinear[src[d + ch]];
          out[o + ch] = _linearToSrgb(sum / 4);
        } else {
          out[o + ch] =
              (src[a + ch] + src[b + ch] + src[c + ch] + src[d + ch] + 2) >> 2;
        }
      }
      out[o + 3] = (src[a + 3] + src[b + 3] + src[c + 3] + src[d + 3] + 2) >> 2;
    }
  }
  return RgbaImage(w, h, out);
}