Reputation: 577
I am using the https://pub.dev/packages/ncnn_yolox_flutter package for object detection in my Flutter app. I want the border outline of detections to look similar to the image below; curved corners only. (Different opacity not necessary, although if anyone knows how to draw that dynamically I would be interested).
What I'm looking for:
I currently have two options working.
e
references my detection results and drawRectPaint
is my decoration):final rect = ui.Rect.fromLTWH(
e.x,
e.y,
e.width,
e.height,
);
canvas.drawRRect(
RRect.fromRectAndRadius(rect, Radius.circular(10.0)),
drawRectPaint,
);
var topLeftPath = Path();
topLeftPath.addPolygon([
Offset((e.x), (e.y + 40)),
Offset((e.x), (e.y)),
Offset((e.x + 40), (e.y)),
], false);
canvas.drawPath(
topLeftPath,
drawRectPaint,
);
Upvotes: 1
Views: 1936
Reputation: 788
Canvas.drawArc(...)
is optimized for drawing arcs and should be faster than Path.arcTo
:
@override
void paint(Canvas canvas, Size size) {
const rect = Rect.fromLTRB(0, 0, 24, 24);
final paint = Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = 5
..strokeCap = StrokeCap.round;
const len = 50.0;
canvas.drawArc(rect, pi, pi / 2, false, paint);
canvas.drawLine(const Offset(0, 12), const Offset(0, len), paint);
canvas.drawLine(const Offset(12, 0), const Offset(len, 0), paint);
canvas.drawArc(rect.translate(_w - 24, 0), 3 * pi / 2, pi / 2, false, paint);
canvas.drawLine(Offset(_w, 12), Offset(_w, len), paint);
canvas.drawLine(Offset(_w - len, 0), Offset(_w - 12, 0), paint);
canvas.drawArc(rect.translate(0, _w - 24), pi / 2, pi / 2, false, paint);
canvas.drawLine(Offset(12, _w), Offset(len, _w), paint);
canvas.drawLine(Offset(0, _w - len), Offset(0, _w - 12), paint);
canvas.drawArc(rect.translate(_w - 24, _w - 24), 0, pi / 2, false, paint);
canvas.drawLine(Offset(_w - len, _w), Offset(_w - 12, _w), paint);
canvas.drawLine(Offset(_w, _w - len), Offset(_w, _w - 12), paint);
}
Upvotes: 0
Reputation: 965
Clever use of PathFillType.evenOdd to darken the outside, and arcTo for the outer lines:
https://dartpad.dartlang.org/?id=20afacc59439722a28c2f7ccea4782bf
class ViewfinderPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final canvasRect = Offset.zero & size;
const rectWidth = 300.0;
final rect = Rect.fromCircle(
center: canvasRect.center,
radius: rectWidth / 2,
);
const radius = 16.0;
const strokeWidth = 6.0;
const extend = radius + 24.0;
const arcSize = Size.square(radius * 2);
canvas.drawPath(
Path()
..fillType = PathFillType.evenOdd
..addRRect(
RRect.fromRectAndRadius(
rect,
const Radius.circular(radius),
).deflate(strokeWidth / 2),
)
..addRect(canvasRect),
Paint()..color = Colors.black26,
);
canvas.save();
canvas.translate(rect.left, rect.top);
final path = Path();
for (var i = 0; i < 4; i++) {
final l = i & 1 == 0;
final t = i & 2 == 0;
path
..moveTo(l ? 0 : rectWidth, t ? extend : rectWidth - extend)
..arcTo(
Offset(l ? 0 : rectWidth - arcSize.width,
t ? 0 : rectWidth - arcSize.width) &
arcSize,
l ? pi : pi * 2,
l == t ? pi / 2 : -pi / 2,
false)
..lineTo(l ? extend : rectWidth - extend, t ? 0 : rectWidth);
}
canvas.drawPath(
path,
Paint()
..color = Colors.deepOrange
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke,
);
canvas.restore();
}
@override
bool shouldRepaint(ViewfinderPainter oldDelegate) => false;
}
Upvotes: 1
Reputation: 1932
You have to use moveTo
, lineTo
and arcTo
to draw border outlines with rounded corners. You need to adjust the values to your needs.
Try this:
topLeftPath.moveTo(e.x, 40);
topLeftPath.relativeLineTo(e.x, -20);
topLeftPath.arcTo(
Rect.fromCenter(
center: Offset(20,20),
width: 40,
height: 40
), math.pi, math.pi/2, false);
topLeftPath.relativeLineTo(20, e.y);
canvas.drawPath(topLeftPath,drawRectPaint);
Upvotes: 1