computePixelationData function
Computes the pixelated representation of an image.
Designed to be run in an isolate via compute
.
Uses the 'image' package for easier pixel access and averaging.
Implementation
List<PixelationBlock> computePixelationData(PixelationComputeData data) {
final List<PixelationBlock> blocks = [];
final int pixelSizeInt = data.pixelSize.round();
if (pixelSizeInt <= 0) {
return blocks; // Avoid division by zero or infinite loops
}
try {
// Decode the image using the image library
// Assuming RGBA format from ui.Image.toByteData(format: ui.ImageByteFormat.rawRgba)
// ignore: unnecessary_nullable_for_final_variable_declarations
final img_lib.Image? image = img_lib.Image.fromBytes(
width: data.imageWidth,
height: data.imageHeight,
bytes: data.byteData.buffer, // Use the buffer
format: img_lib.Format.uint8, // Assuming 8-bit channels
numChannels: 4, // RGBA
);
if (image == null) {
// Handle decoding failure if necessary
return blocks;
}
// Iterate through the image in blocks
for (int y = 0; y < data.imageHeight; y += pixelSizeInt) {
for (int x = 0; x < data.imageWidth; x += pixelSizeInt) {
int totalR = 0;
int totalG = 0;
int totalB = 0;
int totalA = 0;
int pixelCount = 0;
// Calculate bounds for the current block, clamping to image dimensions
final int blockEndX = (x + pixelSizeInt).clamp(0, data.imageWidth);
final int blockEndY = (y + pixelSizeInt).clamp(0, data.imageHeight);
final int blockWidth = blockEndX - x;
final int blockHeight = blockEndY - y;
if (blockWidth <= 0 || blockHeight <= 0) continue; // Skip empty blocks
// Iterate over pixels within the block using image library
for (int py = y; py < blockEndY; py++) {
for (int px = x; px < blockEndX; px++) {
// ignore: unnecessary_nullable_for_final_variable_declarations
final img_lib.Pixel? pixel = image.getPixelSafe(px, py);
if (pixel != null) {
totalR += pixel.r.toInt();
totalG += pixel.g.toInt();
totalB += pixel.b.toInt();
totalA += pixel.a.toInt(); // Assuming alpha channel matters
pixelCount++;
}
}
}
if (pixelCount > 0) {
final int avgR = totalR ~/ pixelCount;
final int avgG = totalG ~/ pixelCount;
final int avgB = totalB ~/ pixelCount;
final int avgA = totalA ~/ pixelCount;
final blockRect = Rect.fromLTWH(
x.toDouble(),
y.toDouble(),
pixelSizeInt.toDouble(), // Use intended pixel size for rect
pixelSizeInt.toDouble(),
);
blocks.add(PixelationBlock(
rect: blockRect,
color: Color.fromARGB(avgA, avgR, avgG, avgB),
));
}
}
}
} catch (e) {
// print("Error during pixelation computation: $e");
// Depending on requirements, you might want to rethrow or return empty/partial list
return blocks; // Return whatever was computed so far or empty
}
return blocks;
}