captureSelection function
Future
captureSelection({
- required GlobalKey<
State< repaintBoundaryKey,StatefulWidget> > - required Rect selection,
- required double pixelRatio,
- required SelectionOutputType outputType,
Captures a portion of a widget defined by a GlobalKey and a selection Rect.
This function is optimized to perform expensive encoding operations in a background isolate to avoid blocking the UI thread.
Implementation
Future<dynamic> captureSelection({
required GlobalKey repaintBoundaryKey,
required Rect selection,
required double pixelRatio,
required SelectionOutputType outputType,
}) async {
try {
final boundary =
repaintBoundaryKey.currentContext?.findRenderObject()
as RenderRepaintBoundary?;
if (boundary == null) return null;
// Capture the full image of the RepaintBoundary
final fullImage = await boundary.toImage(pixelRatio: pixelRatio);
// The selection Rect is in logical pixels; convert to physical pixels for cropping.
final cropRect = Rect.fromLTWH(
selection.left * pixelRatio,
selection.top * pixelRatio,
selection.width * pixelRatio,
selection.height * pixelRatio,
);
// Use a PictureRecorder to crop the image
final recorder = ui.PictureRecorder();
final canvas = Canvas(recorder);
canvas.drawImageRect(
fullImage,
cropRect,
Rect.fromLTWH(0, 0, cropRect.width, cropRect.height),
Paint(),
);
// Create the final cropped image
final croppedImage = await recorder.endRecording().toImage(
cropRect.width.round(),
cropRect.height.round(),
);
// Convert to byte data (this part is relatively fast)
final byteData = await croppedImage.toByteData(
format: ui.ImageByteFormat.png,
);
// Clean up image resources
fullImage.dispose();
croppedImage.dispose();
if (byteData == null) return null;
final imageBytes = byteData.buffer.asUint8List();
// --- Optimization happens here ---
if (outputType == SelectionOutputType.bytes) {
// If the user just wants the bytes, we're done. This is fast.
return imageBytes;
} else {
// If the user wants base64, run the expensive encoding in an isolate.
// The `compute` function spawns an isolate, runs our function, and returns the result.
return await compute(_encodeToBase64InIsolate, imageBytes);
}
} catch (e) {
debugPrint('Error capturing selection: $e');
return null;
}
}