cropImage method

  1. @override
Future<String?> cropImage({
  1. required String path,
  2. required int x,
  3. required int y,
  4. required int width,
  5. required int height,
  6. int rotationDegrees = 0,
  7. bool flipX = false,
  8. int quality = 100,
})
override

Crops, rotates, and flips an image.

Implementation

@override
Future<String?> cropImage({
  required String path,
  required int x,
  required int y,
  required int width,
  required int height,
  int rotationDegrees = 0,
  bool flipX = false,
  int quality = 100,
}) async {
  try {
    // Load image bytes
    Uint8List bytes;
    if (path.startsWith('data:')) {
      bytes = _dataUriToBytes(path);
    } else if (path.startsWith('blob:')) {
      bytes = await _fetchBlobBytes(path);
    } else {
      bytes = await XFile(path).readAsBytes();
    }

    final codec = await ui.instantiateImageCodec(bytes);
    final frame = await codec.getNextFrame();
    final srcImage = frame.image;

    // Rotate + flip via Picture/Canvas
    final recorder = ui.PictureRecorder();
    final rotRad = rotationDegrees * 3.141592653589793 / 180.0;
    int dstW = srcImage.width;
    int dstH = srcImage.height;
    if (rotationDegrees == 90 || rotationDegrees == 270) {
      dstW = srcImage.height;
      dstH = srcImage.width;
    }

    final canvas = ui.Canvas(recorder, ui.Rect.fromLTWH(0, 0, dstW.toDouble(), dstH.toDouble()));
    canvas.translate(dstW / 2, dstH / 2);
    canvas.rotate(rotRad);
    if (flipX) canvas.scale(-1, 1);
    canvas.drawImage(srcImage, ui.Offset(-srcImage.width / 2, -srcImage.height / 2), ui.Paint());

    final transformed = await recorder.endRecording().toImage(dstW, dstH);

    // Crop region
    final cropRect = ui.Rect.fromLTWH(x.toDouble(), y.toDouble(), width.toDouble(), height.toDouble());
    final cropRecorder = ui.PictureRecorder();
    final cropCanvas = ui.Canvas(cropRecorder, cropRect);
    cropCanvas.drawImage(transformed, ui.Offset(-x.toDouble(), -y.toDouble()), ui.Paint());
    final cropped = await cropRecorder.endRecording().toImage(width, height);

    final byteData = await cropped.toByteData(format: ui.ImageByteFormat.png);
    if (byteData == null) return path;

    final pngBytes = byteData.buffer.asUint8List();

    // Return as data URI
    final base64 = _uint8ListToBase64(pngBytes);
    return 'data:image/png;base64,$base64';
  } catch (e) {
    debugPrint('flutter_crop_camera_web: cropImage error: $e');
    return path;
  }
}