capturePhoto method

  1. @override
Future<PickedFile?> capturePhoto({
  1. required bool allowCompression,
  2. required int compressionQuality,
  3. required bool withData,
})
override

Captures a photo using the device camera.

Platform implementations should override this method to handle camera capture on their respective platforms.

Implementation

@override
Future<PickedFile?> capturePhoto({
  required bool allowCompression,
  required int compressionQuality,
  required bool withData,
}) async {
  // mediaDevices is non-nullable in package:web but may be unavailable
  web.MediaStream stream;
  try {
    final constraints = web.MediaStreamConstraints(video: true.toJS);
    stream = await web.window.navigator.mediaDevices
        .getUserMedia(constraints)
        .toDart;
  } catch (_) {
    throw PlatformException(
      code: 'CAMERA_ACCESS_DENIED',
      message: 'Camera permission was denied or camera is unavailable.',
    );
  }

  final imageBytes = await _showCameraDialog(stream);

  // Stop all camera tracks
  final tracks = stream.getTracks();
  for (var i = 0; i < tracks.length; i++) {
    final track = tracks[i] as web.MediaStreamTrack?;
    track?.stop();
  }

  if (imageBytes == null) return null;

  Uint8List finalBytes = imageBytes;
  if (allowCompression) {
    finalBytes = await _compressJpeg(imageBytes, compressionQuality);
  }

  final timestamp = DateTime.now().millisecondsSinceEpoch;
  final fileName = 'captured_photo_$timestamp.jpg';

  final blob = web.Blob(
    [finalBytes.toJS].toJS,
    web.BlobPropertyBag(type: 'image/jpeg'),
  );
  final objectUrl = web.URL.createObjectURL(blob);

  return PickedFile(
    path: objectUrl,
    name: fileName,
    size: finalBytes.length,
    mimeType: 'image/jpeg',
    bytes: withData ? finalBytes : null,
  );
}