takeOverlayCapture method
Future<File?>
takeOverlayCapture(
)
Implementation
Future<File?> takeOverlayCapture() async {
final overlayBox =
_overlayKey.currentContext?.findRenderObject() as RenderBox?;
if (overlayBox == null) {
widget.onError?.call('Error Capturing overlay: Overlay box not found');
return null;
}
final cameraBoundary = _cameraPreviewKey.currentContext?.findRenderObject()
as RenderRepaintBoundary?;
if (cameraBoundary == null) {
widget.onError
?.call('Error Capturing overlay: Camera boundary not found');
return null;
}
// Capture the image using camera controller
final xFile = await widget._controller.cameraController!.takePicture();
final imageBytes = await xFile.readAsBytes();
// Calculate overlay position relative to camera preview
final cameraOffset = cameraBoundary.localToGlobal(Offset.zero);
final overlayOffset = overlayBox.localToGlobal(Offset.zero);
final previewBox = cameraBoundary as RenderBox;
// Create crop data map with all required parameters
final cropData = {
'imageBytes': imageBytes,
'left': overlayOffset.dx - cameraOffset.dx,
'top': overlayOffset.dy - cameraOffset.dy,
'width': overlayBox.size.width,
'height': overlayBox.size.height,
'previewWidth': previewBox.size.width,
'previewHeight': previewBox.size.height,
};
final timestamp = DateTime.now().millisecondsSinceEpoch;
final filename = 'overlay_image_$timestamp.png';
// Process differently based on platform
if (kIsWeb) {
try {
// Convert image bytes to a Blob with explicit MIME type
final blob = web.Blob([cropData['imageBytes']], 'image/png');
final url = web.Url.createObjectUrlFromBlob(blob);
// Create a complete crop data object
final Map<String, dynamic> safeCropData = {
'imageUrl': url.toString(),
'left': cropData['left'] ?? 0,
'top': cropData['top'] ?? 0,
'width': cropData['width'] ?? 0,
'height': cropData['height'] ?? 0,
'previewWidth': cropData['previewWidth'] ?? 0,
'previewHeight': cropData['previewHeight'] ?? 0,
};
// Web worker processing
final croppedPng = await _processWithWebWorker(safeCropData);
// Create file with processed image
final processedBlob = web.Blob([croppedPng], 'image/png');
final path = web.Url.createObjectUrlFromBlob(processedBlob);
return File(filename, 'png', null, path, croppedPng);
} catch (e) {
print('Error in image processing: $e');
widget.onError?.call('Error processing image: $e');
return null;
}
} else {
// Non-web platform processing
try {
final img.Image? decodedImage = img.decodeImage(imageBytes);
if (decodedImage == null) {
widget.onError?.call('Error Capturing overlay: Failed to decode image bytes');
return null;
}
final croppedPng = _cropImageForNonWeb(
decodedImage,
cropData['left'] as double,
cropData['top'] as double,
cropData['width'] as double,
cropData['height'] as double,
cropData['previewWidth'] as double,
cropData['previewHeight'] as double
);
// Save to temp file
final tempDir = await getTemporaryDirectory();
final tempFile = io.File('${tempDir.path}/$filename');
await tempFile.writeAsBytes(croppedPng);
return File(filename, 'png', null, tempFile.path, croppedPng);
} catch (e) {
widget.onError?.call('Error processing image: $e');
return null;
}
}
}