CamerAwesome icon indicating copy to clipboard operation
CamerAwesome copied to clipboard

ML Kit Text Painting Bug / Not compatible with preview

Open FantaMagier opened this issue 7 months ago • 0 comments

Steps to Reproduce

@g-apparence I'm trying a current version from my situation at the time and it runs perfectly on iOS too. Only on Android there are similar problems as with this issue: https://github.com/Apparence-io/CamerAwesome/issues/402 Maybe you remember :D I tried it again but unfortunately it looks like this again:

image

In this example I filter out some words so not all words are marked. What was the solution then?

This is my Painter. I filter words with the for(item in incompabilityList) you can ignore that.

class TextRecognitionPainter extends CustomPainter {
  final RecognizedText? recognizedText;
  final Preview preview;
  final AnalysisImage? analysisImage;
  final CanvasTransformation? canvasTransformation;
  final List<FoodIncomaptible> incompabilityList;
  final bool isPro;

  TextRecognitionPainter({
    required this.recognizedText,
    required this.preview,
    required this.analysisImage,
    required this.incompabilityList,
    required this.isPro,
    this.canvasTransformation,
  });

  @override
  void paint(Canvas canvas, Size size) {
    if (recognizedText == null || analysisImage == null) return;

    if (canvasTransformation != null) {
      canvas.save();
      canvas.applyTransformation(canvasTransformation!, size);
    }

    final Paint background = Paint()..color = const Color(0x99000000);

    for (final textBlocks in recognizedText!.blocks) {
      for (final line in textBlocks.lines) {
        for (final element in line.elements) {
          for (var item in incompabilityList) {
            final ParagraphBuilder builder = ParagraphBuilder(
              ParagraphStyle(
                textAlign: TextAlign.left,
                fontSize: 16,
                textDirection: TextDirection.ltr,
              ),
            );
            builder.pushStyle(ui.TextStyle(color: Colors.red, background: background));
            // builder.addText(textBlocks.text);
            builder.pop();

            final List<Offset> convertedPoints = element.cornerPoints.map((point) {
              return preview.convertFromImage(
                point.toOffset(),
                analysisImage!,
                flipXY: Platform.isAndroid ? true : false,
              );
            }).toList();

            if (element.text.toLowerCase().contains(item.food.translation.toLowerCase()) ||
                item.food.alternativeWords
                    .any((word) => element.text.toLowerCase().contains(word.toLowerCase()))) {
              final Paint paint = Paint()
                ..style = PaintingStyle.stroke
                ..strokeWidth = 3.0
                ..color = getIntoleranceLevelColor(item.level, isPro);

              // final topLeftOffset = element.cornerPoints[0];
              // final bottomRightOffset = element.cornerPoints[2];
              // var topLeftOff = preview.convertFromImage(
              //   topLeftOffset.toOffset(),
              //   analysisImage!,
              //   flipXY: true,
              // );
              // var bottomRightOff = preview.convertFromImage(
              //   bottomRightOffset.toOffset(),
              //   analysisImage!,
              //   flipXY: true,
              // );

              // var _barcodeRect = Rect.fromLTRB(
              //   topLeftOff.dx,
              //   topLeftOff.dy,
              //   bottomRightOff.dx,
              //   bottomRightOff.dy,
              // );

              // canvas.drawRect(
              //   _barcodeRect,
              //   Paint()
              //     ..style = PaintingStyle.stroke
              //     ..color = Colors.blue
              //     ..strokeWidth = 2,
              // );

              // Calculate the bounding box of the element
              final Rect boundingBox = Rect.fromPoints(
                convertedPoints.reduce((a, b) => Offset(
                      a.dx < b.dx ? a.dx : b.dx,
                      a.dy < b.dy ? a.dy : b.dy,
                    )),
                convertedPoints.reduce((a, b) => Offset(
                      a.dx > b.dx ? a.dx : b.dx,
                      a.dy > b.dy ? a.dy : b.dy,
                    )),
              );

              // Add padding only to the right side of the bounding box
              const double rightPadding = 5.0; // Adjust the padding value as needed
              final Rect paddedBoundingBox = Rect.fromLTRB(
                boundingBox.left,
                boundingBox.top,
                boundingBox.right + rightPadding,
                boundingBox.bottom,
              );

              // Create a rounded rectangle with a border radius
              final RRect roundedRect = RRect.fromRectAndRadius(
                paddedBoundingBox,
                const Radius.circular(5.0), // Adjust the radius as needed
              );
              canvas.drawRRect(roundedRect, paint);
            }
          }
        }
      }
    }

    if (canvasTransformation != null) {
      canvas.restore();
    }
  }

  @override
  bool shouldRepaint(covariant TextRecognitionPainter oldDelegate) {
    return recognizedText != oldDelegate.recognizedText ||
        canvasTransformation != oldDelegate.canvasTransformation;
  }
}

About your device

Brand Model OS
Emulator Android 14
Nothing Phone (1) 14

Your flutter version

Run this in your command line flutter --version

Flutter 3.22.2 • channel stable • https://github.com/flutter/flutter.git Framework • revision 761747bfc5 (5 weeks ago) • 2024-06-05 22:15:13 +0200 Engine • revision edd8546116 Tools • Dart 3.4.3 • DevTools 2.34.3

FantaMagier avatar Jul 09 '24 14:07 FantaMagier