applyBlur method
Apply blur effect to the background (person stays sharp).
Mirrors React's blur background effect. Uses the segmentation mask to selectively blur only the background.
Implementation
Future<Uint8List?> applyBlur(
Uint8List frameData, {
required double intensity,
required int width,
required int height,
Uint8List? mask,
}) async {
if (mask == null) return frameData;
try {
// Decode the frame to an image
final codec = await ui.instantiateImageCodec(
frameData,
targetWidth: width,
targetHeight: height,
);
final frameImage = (await codec.getNextFrame()).image;
// Create a picture recorder for compositing
final recorder = ui.PictureRecorder();
final canvas = Canvas(recorder);
final size = Size(width.toDouble(), height.toDouble());
// Calculate blur sigma from intensity (0.0-1.0 → 0-30 sigma)
final sigma = intensity * 30.0;
// Step 1: Draw blurred background
final blurPaint = Paint()
..imageFilter = ui.ImageFilter.blur(
sigmaX: sigma,
sigmaY: sigma,
tileMode: TileMode.clamp,
);
canvas.drawImage(frameImage, Offset.zero, blurPaint);
// Step 2: Draw sharp foreground (person) using mask
// Create mask image from bytes
final maskImage =
await _bytesToImage(mask, width, height, isGrayscale: true);
if (maskImage != null) {
// Use mask as alpha channel to composite original over blur
final maskPaint = Paint()..blendMode = BlendMode.dstIn;
// Draw original frame
canvas.saveLayer(Rect.fromLTWH(0, 0, size.width, size.height), Paint());
canvas.drawImage(frameImage, Offset.zero, Paint());
// Apply mask
canvas.drawImage(maskImage, Offset.zero, maskPaint);
canvas.restore();
maskImage.dispose();
}
// Finalize
final picture = recorder.endRecording();
final resultImage = await picture.toImage(width, height);
final byteData =
await resultImage.toByteData(format: ui.ImageByteFormat.rawRgba);
frameImage.dispose();
resultImage.dispose();
return byteData?.buffer.asUint8List();
} catch (e) {
debugPrint('applyBlur error: $e');
return frameData;
}
}