packLanes function
- List<
PackedLane?> lanes
lanes — red, green, blue, alpha — packed into one RGBA8 image, or null
when every lane is empty.
The size is the largest of the sources, and each is read at the nearest texel to the same place: sources authored at different sizes line up in texture space, which is what their shared coordinates promise.
Implementation
Rgba8Image? packLanes(List<PackedLane> lanes) {
final present = <({Rgba8Image image, int channel})>[
for (final lane in lanes) ?lane,
];
if (present.isEmpty) return null;
final width = present
.map((lane) => lane.image.width)
.reduce((a, b) => a > b ? a : b);
final height = present
.map((lane) => lane.image.height)
.reduce((a, b) => a > b ? a : b);
final pixels = Uint8List(width * height * 4)
..fillRange(0, width * height * 4, 255);
for (final (lane, source) in lanes.indexed) {
if (source == null) continue;
final image = source.image;
for (var y = 0; y < height; y++) {
final sy = (y * image.height) ~/ height;
for (var x = 0; x < width; x++) {
final sx = (x * image.width) ~/ width;
pixels[(y * width + x) * 4 + lane] =
image.pixels[(sy * image.width + sx) * 4 + source.channel];
}
}
}
return Rgba8Image(width: width, height: height, pixels: pixels);
}